Executor Interfaces
Executor
, 태스크를 관리하는 인터페이스 입니다.ExecutorService
는Executor
의 하위 인터페이스이며 태스트와Exector
의 라이프 사이클을 관리하는 기능을 포함하고 있다.ScheduledExecutorService
는ExecutorService
의 하위 인터페이스이며 미래의 태스트에 대한 주기적인 실행을 관리한다.
Executor 인터페이스
Executor
인터페이스는 저수준의 스레드 생성문을 대체할 수 있다.Executor
는 저수준의 스레드 생성문과 동일한 작업을 수행할 수 있지만 차이점은 워크 스레드가 사용 가능해질때까지 큐에 배치할 가능성이 더 크다.
ExecutorService 인터페이스
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Main {
public static void main(String[] args) throws InterruptedException {
ExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
executorService.submit(() -> {
System.out.println("Thread " + Thread.currentThread().getName());
});
executorService.shutdown();
}
}
- 다음작업이 들어올 때가지 계속 대기를 하기 때문에 명시적으로 종료를 시켜줘야 한다.
- 따라서
showdown()
메서드를 사용하여 명시적으로 종료를 시켜줘야 한다.
shutdown() 과 shutdownNow()의 차이점
메서드 주석을 읽어본 결과 다음과 같은 차이가 있었다.
shutdown()
메서드는 이전에 제출된 태스트가 실행이 되고 더 이상 새로운 태스크는 수락하지 않으며 작업을 종료하기 시작한다. 하지만shutdownNow()
메서드는 실행 중인 작업이 종료될 때까지 기다리지 않고 실행중인 작업 처리를 중단 하려는 보장을 할 수 없다고 되어 있다.
ScheduledExecutorService 인터페이스
ScheduledExecutorService
인터페이스는 지정한 지연시간 후에 실행 또는 호출 가능한 태스크를 실행하는 기능을 지원한다.- 지정된 태스크를 정의된 간격으로 반복적으로 실행하는
scheduledWithFixedDelay
및ScheduledAtFixedRate
를 정의합니다.
쓰레드 풀
-
java.util.concurrent
패키지의 Executor 구현은 대부분은 워커 쓰레드로 구성된 쓰레드 풀을 사용한다. 이러한 종류의 스레드는Runnable
및Callable
로 각각 존재하며 여러가지 태스크를 실행하는데 종종 사용된다. -
워커 쓰레드를 사용하면 스레드 생성으로 인한 오버헤드가 최소화 된다. 스레드 개체는 상당한 양의 메모리를 사용하며, 대규모 애플리케이션에서는 많은 스레드 개체를 할당 및 할당 해제하면 상당한 메모리 관리 오버헤드가 발생한다.
-
일반적인 유형의 쓰레드 풀은 쓰레드의 개수가 고정되어 있고 이 유형의 풀에서는 항상 지정된 수의 스레드가 실행되며, 스레드가 동작할 때 갑자기 종료되면 새로운 스레드로 교체되어 실행된다.
-
태스크는 큐를 통해서 풀에 제출되며 풀에 있는 스레드보다 많은 태스크가 있을 때는 잠시 큐에서 대기한다
Runnable 과 Callable의 차이
Runnable
인터페이스는 스레드에 의해서 실행되도록 설계된 모든 클래스에 의해 구현되어야 한다.- 클래스는
Run()
메서드를 정의해야 한다.
- 결과를 반환하고 예외를 발생시킬 수 있는 작업이다.
Callable
인터페이스는 다른 스레드에 의해서 잠재적으로 실행될 수 있다는 점에서Runnable
인터페이스와 유사하지만Runnable
인터페이스는 결과를 반환하지 않으며 선택한 예외를 발생시킬 수 없습니다.
Fork/Join 프레임워크
- 포크/조인 프레임워크는 여러 프로세서를 활용할 수 있도록 지원하는
ExecutorService
인터페이스의 구현이다. - 반복적으로 작은 조각으로 쪼개 질 수 있는 작업을 위해서 고안이 되었다.
- 다른
ExecutorService
구현과 마찬가지로 포크/조인 프레임워크도 쓰레드 풀에 있는 워커 쓰레드에게 작업을 할당한다. - 포크/조인 프레임워크는 워크 스틸링 알고리즘을 사용하는 점에서 차이가 있고 할 일이 부족한 워커 쓰레드는 작동중인 다른 쓰레드에서 작업을 가져올 수 있다.