본문 바로가기
프로그래밍 놀이터/디자인 패턴, 리펙토링

[Effective Java] 스레드 그룹보다는 실행자와 작업을 사용하자.

by 돼지왕 왕돼지 2017. 3. 10.
반응형


 [Effective Java] 스레드 그룹보다는 실행자와 작업을 사용하자.


1.5, awaittermination, cachedthreadpool, callable, catch, concurrent, Effective JAVA, execute, executor, executor framework, executor service, executorcompletionservice, executors, executorservice, invokeall, invokeany, java.util.concurrent, newcachedthreadpool, newFixedThread, newsinglethreadexecutor, Queue, Runnable, scheduledthreadpoolexecutor, shutdown, threadpoolexecutor, timer, unchecked 예외, work queue, [Effective Java] 스레드 그룹보다는 실행자와 작업을 사용하자., 가용할 스레드, 값 반환, 결과, 과도하게 적재된 업무, 다중 스레드, 모든 요소, 새로운 스레드, 서버, 서비스 종료, 설정, 세부적인 사항, 스레드, 스레드 제거, 시간 측정 정확도, 실행자 서비스, 실행자 프레임워크, 앱, 예외, 완료, 유연성, 일부, 작업, 작업 완료, 작은 규모, 작은 규모 프로그램, 적합한 실행자 서비스, 중단, 컬렉션 일부, 패키지, 하나의 스레드


-
자바 1.5 배포판 이후에 java.util.concurrent 패키지가 추가되었다.
여기에는 실행자 프레임워크(Executor Framework) 가 포함되어 있다.
이 녀석을 사용하면 Work queue 를 쉽게 관리할 수 있다.

ExecutorService executor = Executors.newSingleThreadExecutor();

executor.execute(runnable);

executor.shutdown(); // 추가된 task 들의 실행은 보장한다. shutdownNow() 도 있다.


위와 같은 간단한 코드로 쉽게 queue 를 만들어 실행시킬 수 있고,
shutdown 시킬 수 있다.


-
ExecutorService 를 사용하면 정말 많은 일을 할 수 있다.
특정 작업이 완료되기를 기다릴 수 있고,
어떤 컬렉션의 일부 또는 모든 요소에 대한 작업이 완료되기를 기다릴 수 있으며 ( invokeAny, invokeAll - 이들은 collection 을 전달하고, 그 중 한개 혹은 전부가 끝날때까지 기다리는 기능을 한다. )
실행자 서비스의 종료가 완료되기를 기다릴 수 있고( awaitTermination )
작업이 하나씩 끝나는대로 그 결과를 받아 볼 수 있다.(ExecutorCompletionService - Callable 과 연동 )


-
ThreadPoolExecutor 클래스를 직접 사용하여 더 세부적인 사항을 설정하여 사용할 수도 있다.


-
특정 어플에 적합한 실행자 서비스를 선택하기는 쉽지 않다.
만일 작은 규모의 프로그램이나 가볍게 적재되는 서버를 작성하면,
일반적으로 Executors.newCachedThreadPool 메소드를 사용해서 반환된 실행자 서비스를 사용하는 것이 좋다.
CachedThreadPool 은 queue 에 넣지 않고 바로 스레드로 넘겨 실행한다.
만일 가용할 스레드가 없으면 새로운 스레드가 생성된다.
따라서 과도하게 적재된 업무 서버에는 Executors.newFixedThread 를 사용해서 반환된 실행자 서비스(정해진 수의 스레드를 갖는 풀을 제공)을 사용하거나, 스레드 제어를 극대화 하기 위해 ThreadPoolExecutor 클래스를 직접 사용하는 것이 좋다.


-
작업에는 두 종류가 있다.
Runnable 과 Callable(값을 반환하는 것이 Runnable 과 다름).
그리고 작업을 실행하는 일반적인 메커니즘이 executor service 이다.


-
ScheduledThreadPoolExecutor 도 있다.
Timer 가 사용하기는 더 쉬운 반면, 유연성은 ScheduledThreadPoolExecutor 가 훨씬 좋다.
Timer 는 작업 실행을 위해 하나의 스레드만 사용하므로 오래 동안 실행하는 작업이 있을 경우 시간 측정의 정확도가 떨어질 수 있다. 또한 catch 안 된 예외를 던지면 Timer 가 중단된다.
ScheduledThreadPoolExecutor 는 다중 스레드를 지원하고, unchecked 예외를 던지는 작업을 복구한다.





반응형

댓글