문서의 선택한 두 판 사이의 차이를 보여줍니다.
양쪽 이전 판 이전 판 다음 판 | 이전 판 | ||
java:concurrent:executorservice [2016/03/06 21:21] kwon37xi [Basic ExecutorService shutdown Pattern] |
java:concurrent:executorservice [2020/08/07 13:53] (현재) kwon37xi |
||
---|---|---|---|
줄 1: | 줄 1: | ||
====== Java ExecutorService ====== | ====== Java ExecutorService ====== | ||
* [[https:// | * [[https:// | ||
+ | * [[https:// | ||
+ | * [[http:// | ||
* [[http:// | * [[http:// | ||
+ | * [[https:// | ||
+ | * [[http:// | ||
+ | ===== 최적의 쓰레드 풀 수 ===== | ||
+ | '' | ||
+ | < | ||
+ | N쓰레드 = N씨피유 * U씨피유 * (1 + W/C) | ||
+ | </ | ||
+ | * '' | ||
+ | * '' | ||
+ | * '' | ||
+ | * 쓰레드 수가 너무 많으면 오히려 서버가 크래시 될 수 있으므로 **하나의 Executor에서 사용할 쓰레드의 최대 개수는 100이하로 설정하는게 바람직하다** | ||
===== Basic ExecutorService shutdown Pattern ===== | ===== Basic ExecutorService shutdown Pattern ===== | ||
줄 16: | 줄 29: | ||
</ | </ | ||
+ | ===== CahcedThreadPool ===== | ||
+ | <code java> | ||
+ | ExecutorService executorService = Executors.newCachedThreadPool(); | ||
+ | </ | ||
+ | * 이미 쉬고 있는 쓰레드가 있으면 재사용하고 Pool이 꽉차 있으면 새로운 쓰레드를 생성한다. | ||
+ | * 60초 동안 쉰 쓰레드는 풀에서 제거한다. 따라서 장시간 리소스를 점유하지는 않는다. | ||
+ | * 그런데 갯수제한은? | ||
+ | |||
+ | ===== ScheduledExecutor ===== | ||
+ | * '' | ||
+ | * '' | ||
+ | * '' | ||
+ | |||
+ | ===== ExecutorService vs. Fork/Join ===== | ||
+ | * Java 7 에 Fork/Join 추가 | ||
+ | * '' | ||
+ | * Fork/ | ||
+ | |||
+ | ===== ExecutorService 주의점 ===== | ||
+ | * 애플리케이션 종료할 때 올바르게 종료시켜야한다. '' | ||
+ | * 쓰레드 풀 갯수(특히 fixed 일 때)를 너무 적게하면 애플리케이션 성능이 떨어지고 너무 많이하면 불필요한 쓰레드 생성 오버헤드가 증가한다. 갯수 조정에 주의할 것. **CachedThreadPool**을 사용하는게 낫지 않을까? | ||
+ | * 취소된 '' | ||
+ | * '' | ||
+ | * 웹 애플리케이션 등에서 모든 요청마다 '' | ||
+ | |||
+ | ===== ThreadPoolExecutor ===== | ||
+ | * 대표적인 Thread Pool? | ||
+ | * [[https:// | ||
+ | * [[springframework: | ||
+ | * '' | ||
+ | * '' | ||
+ | * '' | ||
+ | * 여기서 매우 중요한 점은 Pool을 늘리는 규칙이다. 이 규칙을 잘 못 이해하면 corePoolSize 만큼의 pool 밖에 안 만들어진다. | ||
+ | |||
+ | > A ThreadPoolExecutor will automatically adjust the pool size (see getPoolSize()) according to the bounds set by corePoolSize (see getCorePoolSize()) and maximumPoolSize (see getMaximumPoolSize()). When a new task is submitted in method execute(Runnable), | ||
+ | > corePoolSize 만큼의 쓰레드가 만들어져 있으면, 그 다음 쓰레드는 queueCapacity만큼 큐에 쌓여 있다가 corePool로 실행이 인입된다. 따라서 corePoolSize가 작고 queueCapacity가 매우 크면 queue가 꽉차기 전까지는 실제로 쓰레드 풀이 확장되지 않고 계속해서 corePool 만 재사용하게 된다. | ||
+ | |||
+ | * reject : Executor가 shutdown 상태이거나, | ||
+ | * '' | ||
+ | |||
+ | ===== ExecutorCompletionService ===== | ||
+ | * [[https:// | ||
+ | * 여러개의 '' | ||
+ | * [[java: | ||
+ | |||
+ | <code java> | ||
+ | final ExecutorService pool = Executors.newFixedThreadPool(5); | ||
+ | |||
+ | // 응답 타입(String) 명시 필요 | ||
+ | final ExecutorCompletionService< | ||
+ | |||
+ | for (final String site : topSites) { | ||
+ | completionService.submit(new Callable< | ||
+ | @Override | ||
+ | public String call() throws Exception { | ||
+ | return IOUtils.toString(new URL(" | ||
+ | } | ||
+ | }); | ||
+ | } | ||
+ | |||
+ | // submit 한 갯수가 정확해야한다. | ||
+ | for(int i = 0; i < topSites.size(); | ||
+ | final Future< | ||
+ | try { | ||
+ | final String content = future.get(); | ||
+ | // | ||
+ | } catch (ExecutionException e) { | ||
+ | log.warn(" | ||
+ | } | ||
+ | } | ||
+ | </ |