ThreadPoolExecutor + Callable + Future Example
본 포스트의 원문은 http://howtodoinjava.com/2015/03/25/threadpoolexecutor-callable-future-example/에서 확인할 수 있으며 원 저작자의 번역 포스팅 허락을 받았음을 알려드립니다.
Executor framework의 장점 중 하나는 task 처리가 끝난 다음 결과를 return 받아 task들을 병렬로(concurrent) 실행할 수 있다는 점입니다. Java Concurrent API의 Callable, Future 두 인터페이스를 활용하는 방법을 살펴보도록 하겠습니다.
먼저 두 인터페이스들을 살펴보겠습니다.
Callable : 이 인터페이스에는 call() 메서드가 있습니다. 이 메소드는 여러분이 task의 로직을 구현해야 합니다. Callable 인터페이스는 parameterized 인터페이스입니다. 즉 call() 메서드가 return 하는 data 타입을 지정해줘야 합니다.
Future : 이 인터페이스는 Callable 객체에서 생성된 결과를 얻을 수 있는 메서드들과 상태를 관리하기 위한 메서드들이 있습니다.
Callable Future Example
이 예제는 Callable 타입의 FactorialCaculator를 만들고 call() 메서드를 override하여 계산을 하고 call() 메서드의 결과를 return 해줍니다. 이 결과는 나중에 메인 프로그램의 Future 레퍼런스에서 찾아 사용하게 됩니다.
이제 factorial 계산기를 2개의 thread와 4개의 임의의 숫자로 테스트해보겠습니다.
Output:
Result for number - 4 -> 24
Result for number - 6 -> 720
Future result is - - 720; And Task done is true
Future result is - - 24; And Task done is true
Result for number - 2 -> 2
Result for number - 6 -> 720
Future result is - - 720; And Task done is true
Future result is - - 2; And Task done is true
Callable 객체를 실행시키기 위해 executor의 submit() 메서드에 전달하여 실행하였습니다. 이 메서드는 Callable 객체를 파라미터로 받아 Future 객체를 리턴으로 돌려주는데 이는 두가지 목적이 있습니다.
a) task의 상태(status) 제어: task를 취소할수 있고 끝났는지 체크할 수 있습니다. isDone() 메서드를 통해 task들이 끝났는지 확인할 수 있습니다.
b) call() 메서드의 return 결과를 얻을 수 있습니다. get() 메서드를 사용하여 Callable 객체의 call() 메서드의 실행이 끝날때까지 기다려 return되는 결과를 받을 수 있습니다. 만약 thread가 get() 메서드로 결과를 기다리고 있는 도중에 interrupt 되면 InterruptedException 예외를 던집니다.
c) Future 인터페이스는 또다른 버전의 get() 메서드를 제공해 줍니다. i.e. get(long timeout, TimeUnit unit). 이 버전의 get 메서드는 task의 결과를 얻을 수 없다면 특정 시간만큼 기다립니다. 만약 특정 시간이 지난 뒤에도 결과를 여전히 얻을수 없다면 메서드는 null 값을 return합니다.