Java Adv 23 - Executor framework
in Programming Language on Java
Callable
java.util.concurrent.Executors 가 제공하는 newFixedThreadPool(size) 을 사용하면 편리하게 ExecutorService 를 생성할 수 있다.
기존 코드
ExecutorService es = new ThreadPoolExecutor(1,1,0, TimeUnit.MILLISECONDS, new
LinkedBlockingQueue<>());
편의 코드
ExecutorService es = Executors.newFixedThreadPool(1);
MyCallable은 숫자를 반환하는 Callable 인터페이스를 구현한 클래스이다. 이 인터페이스를 활용하면 작업 완료 후 결과를 반환할 수 있다는 점에서 Runnable과 차이가 있다. Runnable은 작업 결과를 직접 반환할 수 없기 때문에 결과를 저장할 별도의 필드를 만들어야 하지만, Callable은 결과를 반환하는 기능을 제공하기 때문에 필드 없이 구현이 가능하다. ExecutorService는 submit() 메서드를 통해 Callable 작업을 스레드 풀에 전달할 수 있게 한다. submit() 메서드는 Future라는 특별한 인터페이스를 반환하며, 이를 통해 비동기적으로 작업 결과를 확인하거나 가져올 수 있다. 예를 들어, MyCallable 인스턴스를 submit() 메서드에 전달하면 해당 작업은 블로킹 큐에 추가되고, 스레드 풀의 스레드 중 하나가 이를 실행한다.
Future<Integer> future = es.submit(new MyCallable());
작업의 처리 결과는 Future 객체를 통해 얻을 수 있다. get() 메서드를 호출하면 MyCallable의 call() 메서드가 반환한 결과를 받을 수 있으며, 작업이 완료될 때까지 호출부가 블로킹된다.
Integer result = future.get();
이 과정에서 get() 메서드는 InterruptedException과 ExecutionException이라는 체크 예외를 던질 수 있다. 예외는 필요에 따라 적절히 처리하거나 호출부로 전달할 수 있다. Executor 프레임워크의 가장 큰 강점은 스레드를 생성하거나 제어하는 복잡한 작업을 하지 않아도 멀티스레드 환경을 쉽게 활용할 수 있다는 점이다. Callable을 사용하면 작업 결과를 반환받아야 하는 상황에서도 편리하며, 개발자는 단순히 작업을 ExecutorService에 제출하고 결과를 받아 사용하는 방식으로 구현할 수 있다. 복잡한 멀티스레드 작업을 간단하게 처리할 수 있도록 해주는 것이 Executor 프레임워크의 핵심적인 장점이다.
Reference
김영한님의 자바 강의
https://docs.oracle.com/javase/tutorial/essential/concurrency/sync.html