정적 팩토리 메소드 Executors.newCachedThreadPool() 는 스레드를 재사용할 수 있는 스레드풀을 만들어준다.
이 스레드풀 안에서 수행이 완료된 스레드는 바로 소멸되지 않고
풀 안에서 (기본값을 바꾸지 않았다면) 60초 동안 TIMED_WAITING 상태로 재사용되기를 기다린다.
재사용되지 않고 60초가 지나면 풀에서 제거된다.
직접 확인해보자.
public class Hello {
public static void main(String[] args) throws IOException, InterruptedException {
Executor pool = Executors.newCachedThreadPool();
// 풀 안에 스레드 생성 및 실행
pool.execute(new Runnable() {
@Override
public void run() {
System.out.println("hello cached thread pool!");
// 특별히 하는 일 없이 바로 종료
}
});
// 덤프파일 확인할 수 있도록, 2분 동안 프로세스 살려두자.
for(int i=1; i <= 120; i ++) {
Thread.sleep(1000);
System.out.println(i + " seconds: " + pool.toString());
// 스레드덤프파일 생성 명령
// $ jstack {pid} > dumps.log
// 60초 전과 후의 덤프파일 내용을 비교해보자.
}
}
}
위 코드를 실행시키고, 프로세스가 살아있는 동안 스레드 덤프파일을 생성해보자.
$ jstack {pid} > dumps.log
60초 경과 전과 후에 생성된 덤프파일을 비교해보자.
60초 경과전 덤프파일
... 생략 ...
"pool-1-thread-1" #13 prio=5 os_prio=0 tid=0x0000000016ebc800 nid=0x3e20 waiting on condition [0x0000000017acf000]
java.lang.Thread.State: TIMED_WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000000eb30e498> (a java.util.concurrent.SynchronousQueue$TransferStack)
at java.util.concurrent.locks.LockSupport.parkNanos(Unknown Source)
at java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(Unknown Source)
at java.util.concurrent.SynchronousQueue$TransferStack.transfer(Unknown Source)
at java.util.concurrent.SynchronousQueue.poll(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.getTask(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
... 생략 ...
60초 경과후 덤프파일
"덤프파일에서 해당 스레드가 사라졌다"
console에 찍힌 로그에서도 pool의 스레드 통계를 확인 할 수 있다. 60초가 경과 하면 pool size가 줄었다.
... 생략 ...
58 seconds: java.util.concurrent.ThreadPoolExecutor@70dea4e[Running, pool size = 1, active threads = 0, queued tasks = 0, completed tasks = 1]
59 seconds: java.util.concurrent.ThreadPoolExecutor@70dea4e[Running, pool size = 1, active threads = 0, queued tasks = 0, completed tasks = 1]
60 seconds: java.util.concurrent.ThreadPoolExecutor@70dea4e[Running, pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 1]
61 seconds: java.util.concurrent.ThreadPoolExecutor@70dea4e[Running, pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 1]
... 생략 ...
'아는 만큼 보인다 > Concurrency' 카테고리의 다른 글
Java 클래스 멤버 변수들의 초기화 순서 (0) | 2014.11.21 |
---|---|
Thread pool 에서 결과(Future) 받기 (0) | 2014.11.19 |
Thread 상태 (0) | 2014.11.19 |
Thread-Safe 를 위한 Keywords (0) | 2014.11.19 |
Executors 팩토리 클래스 (0) | 2014.11.18 |