백기선(인프런 강의)/더 자바, Java 8
Callable과 Future
레알윙
2020. 7. 20. 13:04
반응형
Callable
- Runnable과 유사하지만 작업의 결과를 받을 수 있다.
Future
- 비동기적인 작업의 현재 상태를 조회하거나 결과를 가져올 수 있다.
- https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Future.html
get() - 결과를 가져오기
- 블록킹 콜
- 결과를 가져올때까지 기다린다.
- 타임아웃(최대한으로 기다릴 시간)을 설정 가능
public class App {
public static void main(String[] args) throws InterruptedException, ExecutionException {
ExecutorService executorService = Executors.newSingleThreadExecutor();
Future<String> helloFuture = executorService.submit(() -> {
Thread.sleep(2000L);
return "Callable";
});
System.out.println("Hello");
String result = null;
result = helloFuture.get();
helloFuture.get(); //블록킹콜
System.out.println(result);
executorService.shutdown();
}
}
작업 상태 확인하기 isDone()
- 완료 했으면 true 아니면 false를 리턴한다.
public class App {
public static void main(String[] args) throws InterruptedException, ExecutionException {
ExecutorService executorService = Executors.newSingleThreadExecutor();
Callable<String> hello = () -> {
Thread.sleep(2000L);
return "Hello";
};
Future<String> helloFuture = executorService.submit(hello);
System.out.println(helloFuture.isDone());
System.out.println("Startd!");
helloFuture.get(); //블록킹콜
System.out.println(helloFuture.isDone());
System.out.println("End!");
executorService.shutdown();
}
}
작업 취소하기 cancel()
- 취소 했으면 true 못했으면 false를 리턴한다.
- parameter로 true를 전달하면 현재 진행중인 쓰레드를 interrupt하고 그러지 않으면 현재 진행중인 작업이 끝날때까지 기다린다.
public class App {
public static void main(String[] args) throws InterruptedException, ExecutionException {
ExecutorService executorService = Executors.newSingleThreadExecutor();
Callable<String> hello = () -> {
Thread.sleep(2000L);
return "Hello";
};
Future<String> helloFuture = executorService.submit(hello);
System.out.println(helloFuture.isDone());
System.out.println("Startd!");
helloFuture.cancel(false);
//아래의 isdone은 위에서 cancel을 했기 때문에 값을 가져오는 것
System.out.println(helloFuture.isDone());
System.out.println("End!");
executorService.shutdown();
}
}
위의 코드에서 cancel 끝나고 isDone으로 가져오게 되면 아래와같은 오류가 발생이된다.
발생 이유는 종료가 되었기 때문이다.
여러 작업 동시에 실행하기 invokeAll()
- 동시에 실행한 작업 중에 제일 오래 걸리는 작업 만큼 시간이 걸린다.
- 모든 결과가 나올때까지 기다린다.
public class App {
public static void main(String[] args) throws InterruptedException, ExecutionException {
ExecutorService executorService = Executors.newSingleThreadExecutor();
Callable<String> hello = () -> {
Thread.sleep(2000L);
return "Hello";
};
Callable<String> java = () -> {
Thread.sleep(2000L);
return "java";
};
Callable<String> jinSeok = () -> {
Thread.sleep(2000L);
return "jinSeok";
};
List<Future<String>> futures = executorService.invokeAll(Arrays.asList(hello, java, jinSeok));
for(Future<String> f : futures) {
System.out.println(f.get());
}
executorService.shutdown();
}
}
여러 작업 중에 하나라도 먼저 응답이 오면 끝내기 invokeAny()
- 동시에 실행한 작업 중에 제일 짧게 걸리는 작업 만큼 시간이 걸린다.
- 블록킹 콜이다.
public class App {
public static void main(String[] args) throws InterruptedException, ExecutionException {
ExecutorService executorService = Executors.newFixedThreadPool(4);
Callable<String> hello = () -> {
Thread.sleep(2000L);
return "Hello";
};
Callable<String> java = () -> {
Thread.sleep(3000L);
return "java";
};
Callable<String> jinSeok = () -> {
Thread.sleep(1000L);
return "jinSeok";
};
String s = executorService.invokeAny(Arrays.asList(hello, java, jinSeok));
System.out.println(s);
executorService.shutdown();
}
}
단, 싱글 쓰레드로 할경우 먼저 들어간 순서대로 나오게된다.
반응형