import java.util.concurrent.*;
public class FutureExercise {
public static void main(String[] args) throws ExecutionException, InterruptedException {
ExecutorService executorService = Executors.newSingleThreadExecutor();
Callable<String> hello = () -> {
Thread.sleep(2000L);
System.out.println("RUNNING");
return "Hello";
};
// 정의한 Callable을 사용하는 방법
Future<String> submit = executorService.submit(hello);
System.out.println("Started!");
System.out.println(submit.isDone()); // 끝났으면 true, 안 끝났으면 false
submit.get(); // get을 만난 순간부터 멈춰서 기다림(블록킹이라고 함).
// 마냥 기다리기만 하는것이 아니라 상태도 확인할 수 있음
System.out.println(submit.isDone()); // 끝났으면 true, 안 끝났으면 false
// 진행중인 작업을 취소하는 기능도 제공됨
// parameter로 true를 주면 현재 진행 중인 작업을 interrupt하면서, 종료
// false는 현재 진행 중인 작업을 기다리고, 종료
// 일단 cancel을 하고나면, get을 통해 가져오는것은 불가능해짐.
// 그리고 cancel을 하고나면, isDone은 true가 됨.(값을 가져갈 수 있다는 의미의 종료가 아닌 캔슬로 인한 종료)
submit.cancel(true);
System.out.println("End!");
executorService.shutdown();
}
}
>>>
Started!
false
RUNNING
true
End!
get()
: Future 타입으로 결과를 가져오는 메서드, 타임아웃(최대한으로 기다릴 시간)을 설정할 수 있다.isDone()
: 상태를 확인할 수 있는 메서드, 만약 작업이 끝났으면 true, 끝나지 않았으면 false를 return한다.cancel()
: 작업을 취소하는 메서드로써, 취소에 성공하면 true, 못했으면 false를 리턴한다.
import java.util.List;
import java.util.Arrays;
import java.util.concurrent.*;
public class FutureExercise2 {
public static void main(String[] args) throws InterruptedException, ExecutionException {
// ExecutorService es = Executors.newSingleThreadExecutor();
ExecutorService es = Executors.newFixedThreadPool(4);
Callable<String> hello = () -> {
Thread.sleep(2000L);
return "Hello";
};
Callable<String> java = () -> {
Thread.sleep(3000L);
return "Java";
};
Callable<String> nathan = () -> {
Thread.sleep(1000L);
return "Nathan";
};
// 여러 Callable을 한꺼번에 보낼 수 있음 : invokeAll, invokeAny
// invokeAll : 그러나 모든 작업이 끝날때까지 기다린 후 결과를 가져옴
// List<Future<String>> futures= es.invokeAll(Arrays.asList(hello, java, nathan));
// for (Future<String> f : futures){
// System.out.println(f.get());
// }
// invokeAny : 바로 가장 빨리 끝난 결과가 나옴(Future가 아닌, 바로 그 타입으로)
String futures2= es.invokeAny(Arrays.asList(hello, java, nathan));
System.out.println(futures2); // 싱글스레드일때는 기다린 초가 가장 짧은것과 별개로 가장 먼저 실행한게 나오는듯?
// 스레드 여러개를 만들었을 때는 기다린 초가 가장 짧은게 출력되었음.
es.shutdown();
}
}
>>>
Nathan
invokeAll()
: 여러 작업을 동시에 실행한뒤 결과를 가져오는 메서드. 동시에 실행한 작업 중에 제일 오래 걸리는 작업만큼 시간이 걸린다.
invokeAny()
: 여러 작업 중에 하나라도 먼저 응답이 오면 끝내는 메서드. 동시에 실행한 작업 중에 제일 짧게 걸리는 작업만큼 시간이 걸린다.