JAVA/JAVA8 관련
CompletableFuture2
JUMP개발자
2022. 5. 31. 16:54
CompletableFuture는 별다른 Executor를 사용하지 않아도 ForkJoinPool에 있는 Common Pool을 사용한다.
하지만 원한다면 직접 쓰레드풀을 만들어서 사용할 수 있다. 아래 예제와 같이 runAsync()나 supplyAsync() 메서드를 호출할 때 2번째 인자로 줄 수 있다. 콜백을 실행할 풀을 다른곳에서 실행할때에는 thenRunAsync, thenAcceptAsync, thenRunAsync 등을 사용하면된다.
public class CompletableFutureP2 {
public static void main(String[] args) throws InterruptedException, ExecutionException {
ExecutorService executorService = Executors.newFixedThreadPool(4);
CompletableFuture<Void> future = CompletableFuture.supplyAsync(() -> {
System.out.println("Thread1 :: " + Thread.currentThread().getName());
return "Hello";
}, executorService).thenRunAsync(() -> {
System.out.println("Thread2 :: " + Thread.currentThread().getName());
}, executorService);
future.get();
executorService.shutdown();
}
}
조합하기
thenCompose() : 두작업이 서로 이어서 실행되도록 한다. 두 작업이 서로 연관관계가 있을 때 사용함.
public class CompletableFutureP3 {
public static void main(String[] args) throws InterruptedException, ExecutionException {
CompletableFuture<String> hello = CompletableFuture.supplyAsync(() -> {
System.out.println("HI " + Thread.currentThread().getName());
return "HI";
});
CompletableFuture<String> future = hello.thenCompose(CompletableFutureP3::getWorld);
System.out.println(future.get());
}
private static CompletableFuture<String> getWorld(String message) {
return CompletableFuture.supplyAsync(() -> {
System.out.println("THERE : " + Thread.currentThread().getName());
return message + " THERE";
});
}
}
thenCombine() : 독립적인 두작업을 실행하고 둘 다 종료됬을 때 콜백을 실행한다.
두 작업이 서로 연관관계가 없어 모두 완료된 결과를 바탕으로 추가 작업을 하고 싶을 때 사용한다.
public class CompletableFutureP4 {
public static void main(String[] args) throws InterruptedException, ExecutionException {
CompletableFuture<String> hi = CompletableFuture.supplyAsync(() -> {
System.out.println("HI " + Thread.currentThread().getName());
return "HI";
});
CompletableFuture<String> there = CompletableFuture.supplyAsync(() -> {
System.out.println("THERE : " + Thread.currentThread().getName());
return "THERE";
});
CompletableFuture<String> future = hi.thenCombine(there, (h, w) -> h + " " + w); // BiFunction
System.out.println(future.get());
}
}
allOf() : 여러작업을 실행하고 모든 작업 결과에 콜백을 실행.
anyOf() : 여러작업 중에 가장 빨리 끝난 결과의 콜백을 실행.
예외처리하기
exceptionally(function)
public class CompletableFutureP6 {
public static void main(String[] args) throws InterruptedException, ExecutionException {
boolean throwError = true;
CompletableFuture<String> hi = CompletableFuture.supplyAsync(() -> {
if(throwError) {
throw new IllegalArgumentException();
}
System.out.println("hi " + Thread.currentThread().getName());
return "hi";
}).exceptionally(ex -> {
System.out.println(ex);
return "Error!";
});
}
}
handle(function) : 첫번째 파라메터는 정상적인 결과의 경우 결과값, 두번째 파라메터는 예외 발생 시 에러를 넣어서 처리함. 즉 정상일 경우와 에러 발생 경우를 모두 처리가능함.
public class CompletableFutureP7 {
public static void main(String[] args) throws InterruptedException, ExecutionException {
boolean throwError = true;
CompletableFuture<String> hi = CompletableFuture.supplyAsync(() -> {
if(throwError) {
throw new IllegalArgumentException();
}
System.out.println("Hi " + Thread.currentThread().getName());
return "Hi";
}).handle((result, error) -> {
if(error != null) {
System.out.println(error);
return "ERROR!!!!!!!";
}
return result;
});
}
}