자바는 ThreadPool을 위해 java.util.concurrent패키지에서 ExecutorService interface와 Executor 클래스를 제공
Executor의 다양한 정적 메소드를 이용해 ExecutorService 구현 객체를 만들 수 있음
ExecutorService(스레드풀)에서는 작업 처리를 위해 두 가지 메소드가 제공됨
execute()와 submit()
1)execute()
- 리턴값이 없는 Runnable객체를 작업큐에 저장 -> 작업처리 결과를 받지 못함
- 작업 처리 도중에 예외가 발생하면 스레드가 종료되고 해당 스레드를 스레드풀에서 제거한 뒤 다른 작업처리를 위해 새로운 스레드를 생성함
2)submit()
- 작업처리결과를 받을 수 있도록 Future를 리턴
- 작업처리 도중에 예외가 발생하더라도 스레드는 종료되지 않고 다음 작업을 위해 재사용됨
--> 스레드 생성 오버헤더를 줄이기 위해 submit()사용하는 것이 좋음
1) Executor
< Executor 인터페이스를 구현한 클래스의 기능>
<구조>
프로듀서-컨슈머 패턴에 기반
작업을 생성해 등록하는 클래스가 프로듀서(처리해야할 작업을 생성하는 주체)
작업을 실제로 실행하는 스레드가 컨슈머(생성된 작업을 처리하는 주체)
일반적으로 프로듀서-컨슈머 패턴을 애플리케이션에 적용해 구현할 수 있는 가장 쉬운 방법이 Executor Framework를 사용하는 것
1) Executors.newFixedThreadPool(100); //100개의 스레드
- 처리할 작업이 등록되면 그에 따라 실제 작업할 스레드를 하나씩 생성
- 생성할 수 있는 스레드의 최대 개수는 제한되어 있음
- 제한된 개수까지 스레드를 생성하고 나면 더 이상 생성하지 않고 스레드 수를 유지함
2) Executors.newCachedThreadPool();
- 캐시 스레드풀은 현재 풀에 갖고 있는 스레드의 수가 처리할 작업의 수보다 많아서 쉬는 스레드가 많이 발생할 때 쉬는 스레드를 종료시켜 훨씬 유연하게 대응할 수 있음
- 처리할 작업의 수가 많아지면 필요한 만큼 스레드를 새로 생성함
- 스레드의 수에 제한을 두지 않음
3) Executors.newSingleThreadExecutor();
- 단일 스레드로 동작하는 Executor로서 작업을 처리하는 스레드가 단 하나
- 만약 작업 중에 Exception이 발생해 비정상적으로 종료되면 새로운 스레드를 하나 생성해 나머지 작업을 실행함
- 등록된 작업은 설정된 큐에서 지정하는 순서(FIFO, LIFO, 우선순위)에 따라 반드시 순차적으로 처리됨
4) Executor.newScheduledThreadPool(100);
- 일정시간 이후에 실행하거나 주기적으로 작업을 실행할 수 있으며, 스레드의 수가 고정되어 있는 형태의 Executor.Timer 클래스의 기능과 유사함
2) ExecutorService
3) ThreadPoolExecutor
-Executors 클래스에 들어있는 newCachedThreadPool ,newFixedThreadPool,newScheduledThreadPool과 같은 팩토리메소드에서 생성해 주는 Executor에 대한 기본적인 내용이 구현되어 있는 클래스