ThreadPoolExecutor (java.util.concurrent)
java.util.concurrent ํจํค์ง์๋ ThreadPoolExecutor๋ผ๋ ์ด๋ฆ์ ๋ฒ์ฉ ์ค๋ ๋ ํ ๊ตฌํ์ฒด๊ฐ ์ถ๊ฐ๋์์ต๋๋ค.
ํด๋น ํจํค์ง ์ด์ ์๋ ๋ชจ๋ ์๋ธ๋ฆฟ ์ปจํ
์ด๋๊ฐ ๋
์์ ์ธ ์ค๋ ๋ ํ์ ๊ตฌํํด ์ฌ์ฉํ์ง๋ง,
ํ์ฌ ๋๋ถ๋ถ์ ๊ตฌํ์ฒด๋ ThreadPoolExecutor ๊ตฌํ์ฒด๋ก ์ค๋ ๋ ํ ๊ตฌํ์ ๊ต์ฒดํ๊ฑฐ๋
์ต์ํ ThreadPoolExecutor์ ์ธํฐํ์ด์ค๋ฅผ ๋ง์ถ ๊ตฌํ์ฒด๋ฅผ ์ ๊ณตํฉ๋๋ค.
์ด ThreadPoolExecutor ์ค๋ ๋ ํ ๊ตฌํ์ฒด๊ฐ ๊ธฐ์กด์ ์ค๋ ๋ ํ์ ๋นํด ์๋ฑํ ์ฑ๋ฅ์ ๊ฐ์ก๋ค๊ณ ์
์ฆ๋์ด ๊ทธ๋ ๋ค๊ธฐ๋ณด๋ค๋
์ธ์ด ์์ฒด์์ ์ ๊ณตํ๋ ํ์ค ๊ตฌํ์ฒด๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ์๋ธ๋ฆฟ ์ปจํ
์ด๋๋ฅผ ๊ตฌํํ๋ ์ฌ๋๋ค ์ฌ์ด์์๋
์ถ๊ฐ ์ปค๋ฎค๋์ผ์ด์
๋น์ฉ์ ์ค์ผ ์ ์๊ธฐ ๋๋ฌธ์ด๋ผ๊ณ ํ ์ ์์ต๋๋ค.
์๋ ์ฝ๋๋ 1๋ฒ๋ถํฐ 13๋ฒ๊น์ง ์ฐจ๋ก๋๋ก ์ถ๋ ฅ๋๋ ๊ฒ์ ํ์ธํ ์ ์์ต๋๋ค.
public class WalkSerial {
private Object lock = new Object();
private void printMessage(int index) {
synchronized (lock) {
try {
lock.wait(1000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.printf("%d๋ฒ์งธ MinGOOD ์
์ฅ\n", index);
}
}
private void action(int size) {
System.out.printf("%d๋ช
์ MinGOOD ๋ถ์ ์ \n", size);
for (int i = 0; i < size; ++i) {
printMessage(i+1);
}
}
public static void main(String[] args) {
WalkSerial ws = new WalkSerial();
System.out.println("์ฐจ๋ก๋๋ก ์ถ๋ ฅ๋๋ ์์ ");
ws.action(10);
}
}
์๋์ฝ๋๋ ThreadPoolExecutor ์์ ์
๋๋ค.
package com.study.threadpool;
class People implements Runnable {
private int index;
private Object lock = new Object();
public People(int index) {
this.index = index;
}
@Override
public void run() {
synchronized (lock) {
try {
lock.wait(1000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.printf("%d๋ฒ์งธ MinGOOD ์
์ฅ\n", index);
}
}
}
package com.study.threadpool;
import java.util.concurrent.*;
public class WalkParallel {
private void action(int size) {
System.out.printf("%d๋ช
์ MinGOOdD ๋ถ์ ์ \n", size);
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(10, 20, 60, TimeUnit.SECONDS, new SynchronousQueue<Runnable>());
for (int i = 0; i < size; ++i) {
threadPoolExecutor.execute(new People(i + 1));
}
threadPoolExecutor.shutdown();
}
public static void main(String[] args) {
WalkParallel wp = new WalkParallel();
System.out.println("ThreadPoolExecutor ์์ ");
wp.action(10);
}
}
์ ์ฒด ์ํ์ 2์ด ๋ด๋ก ์ข
๋ฃ๋๋ฉฐ, ์์์ ์๊ด์์ด ๋ฌด์์๋ก ๋ํ๋ฉ๋๋ค.
๋ํ, ์ค๋ ๋ ํ์ ๋ด๋ถ์ ์์ฒญ์ด ๋ค์ด์์ ๋ ์ฒ๋ฆฌํ๊ธฐ ์ํด ๋๊ธฐ ์ํ์ ์ค๋ ๋๋ฅผ ๊ณ์ ์ ์งํ๋ฏ๋ก
ํ์ฌ ์์
ํ๊ฐ ๋น์๋ค๊ณ ์๋์ผ๋ก ์ข
๋ฃ๋์ง ์์ต๋๋ค.
์ ์์ ์์๋ shutdown ๋ฉ์๋๋ฅผ ํธ์ถํด ์ค๋ ๋ ํ ์์ฒด๋ฅผ ์ข
๋ฃ์์ผฐ์ต๋๋ค.
์๋ธ๋ฆฟ ์ปจํ
์ด๋๋ ThreadPoolExecutor์ LifeCycle์ ์ ์ ํ ๊ด๋ฆฌํด์ฃผ์ด์ผ ํฉ๋๋ค.
ThreadPoolExecutor ์ฌ์ฉ
ThreadPoolExecutor์ ์ฌ์ฉ์ ๋น๊ต์ ์ง๊ด์ ์ผ๋ก ์ดํดํ ์ ์์ต๋๋ค.
๋ณ๋ ฌ๋ก ์ํํ ์์
์ Runnable ํ์
์ผ๋ก ์์ฑํด ThreadPoolExecutor์ executor ๋ฉ์๋ ์ธ์๋ก ๋๊ฒจ์ฃผ๊ธฐ๋ง ํ๋ฉด ๋ฉ๋๋ค.
์ฌ๊ธฐ์ ์ฃผ์ํ ์ ์ ์์
ํ๋ก ์ฌ์ฉํ BlockingQueue์ ์ฑ์ง์ ๋ฐ๋ผ ๋ฏธ๋ฌํ๊ฒ 3๊ฐ์ง ๋ค๋ฅธ ์ํ ๋ฐฉ์์ด ์๋ค๋ ๊ฒ์
๋๋ค.
์์ ์์ ์ฌ์ฉํ SynchronousQueue๋ ์ํ ์์ฒญ์ด ๋ค์ด์ค๋ฉด
์์ฒญ์ ์์๋์ง ์๊ณ ํ ๋ด์ ์ค๋น๋ ์ค๋ ๋๋ฅผ ์ฆ์ ๋งค์นญํ์ฌ ์ฒ๋ฆฌํฉ๋๋ค.
๋ฐ๋ผ์ ์ค๋ ๋ ํ ๋ด์ ์ค๋น๋ ์ค๋ ๋๊ฐ ๋ชจ๋ ๋ค๋ฅธ ์ผ์ ์ํํ๋ค๋ฉด,
์ต๋ ๊ฐ๋ฅ ์ค๋ ๋ ์๊ฐ ์ด๊ณผ๋์ง ์๋ ํ ์ฆ์ ์ ์ค๋ ๋๋ฅผ ์์ฑํด ์์ฒญ์ ์ฒ๋ฆฌํฉ๋๋ค.
์ต๋ ๊ฐ๋ฅ ์ค๋ ๋ ์ด์์ ์์ฒญ์ด ๋ค์ด์ค๋ฉด ํด๋น ์์ฒญ์ ๋ฒ๋ ค์ง๋ฏ๋ก
์ต๋ ๊ฐ๋ฅ ์ค๋ ๋ ์๋ ์ ํ์ด ์๊ฒ ํฌ๊ฒ ์ค์ ํ๋ ๊ฒ์ด ์ผ๋ฐ์ ์
๋๋ค.
๋ฐ๋ผ์, ์ฒ๋ฆฌ๋๋ ์๋๋ณด๋ค ์์ฒญ์ด ๋ค์ด์ค๋ ์๋๊ฐ ๋ ๋น ๋ฅด๋ฉด ์ค๋ ๋์ ์๊ฐ ๋น์ ์์ ์ผ๋ก ์ฆ๊ฐํ ์ ์์ต๋๋ค.
๋๋จธ์ง ๋ ๋ฐฉ์์ ์ต๋ ๊ฐ๋ฅ ์ค๋ ๋ ์์ ์ ํ ์๋ ํ๋ฅผ ์ฌ์ฉํ๋ ๋ฐฉ์๊ณผ ์ ํ ์๋ ํ๋ฅผ ์ฌ์ฉํ๋ ๋ฐฉ์์
๋๋ค.
์ด ๋ ๋ฐฉ์์๋ ์ค์ง์ ์ผ๋ก ์ต๋ ๊ฐ๋ฅ ์ค๋ ๋ ์๋ ์๋ฏธ๊ฐ ์์ต๋๋ค.
์๋ํ๋ฉด, ThreadPoolExecutor ์์ฑ์์ ์ฒซ ๋ฒ์งธ ์ธ์์ธ corePoolSize ์๋งํผ๋ง ์ค๋ ๋๋ฅผ ์ฌ์ฉํด ๋์ํ๋ฉฐ,
์ด์์ ์์ฒญ์ด ๋ค์ด์ค๋ฉด ์ค๋ ๋์ ์๋ฅผ ๋๋ฆฌ๋ ๋์ ์ถ๊ฐ ์์ฒญ์ ์์
ํ์ ์์ ๋๊ณ ์ฒ๋ฆฌํฉ๋๋ค.
์์ ๊ฒฝ์ฐ์ ๊ฐ์ด ์ฒ๋ฆฌ๋๋ ์๋๋ณด๋ค ์์ฒญ์ด ๋ค์ด์ค๋ ์๋๊ฐ ๋ ๋น ๋ฅผ ๊ฒฝ์ฐ
์ ํ ์๋ ํ(LinkedBlockingQueue)๋ ํ์ ํฌ๊ธฐ๊ฐ ๋น์ ์์ ์ผ๋ก ์ปค์ง๋ ๋ฌธ์ ๊ฐ ๋ฐ์ํ ์ ์์ต๋๋ค.
๋ฐ๋ฉด, ์ ํ ์๋ ํ(ArrayBlockingQueue)๋ ๋ฏธ๋ฆฌ ์ ํด์ง ํ ์ฌ์ด์ฆ๋ฅผ ๋๋ ์์ฒญ์ ๋ชจ๋ ๋ฒ๋ฆฝ๋๋ค.
๋ฐ๋ผ์, ์ด ์ธ ํ์
์ ๋ชจ๋ ์๋ก ๊ธฐ๋ฅ ๋ฐ ์์ ์ฑ์ ๋ํ Trade-Off๊ฐ ์์ผ๋ฉฐ,
์ด๋ค ํ์
์ด ์ธ์ ๋ ์ณ์ ๊ฒ์ด ์๋๋ผ ์ฌ์ฉ๋๋ ์ํฉ์ ๋ง๊ฒ ์ ์ ํ ์ ํํด์ผ ํฉ๋๋ค.
๋๋ถ๋ถ์ ์๋ธ๋ฆฟ ์ปจํ
์ด๋์๋ ์๋ธ๋ฆฟ์ ๋์์ํค๋ ์ค๋ ๋์ ์ซ์๋ฅผ ์ค์ ํ ์ ์์ต๋๋ค.
์ฆ, ์๋ธ๋ฆฟ์ ์ฒ๋ฆฌํ๊ธฐ ์ํด ์ค๋ ๋ ํ์ด ๋ด๋ถ์ ์ผ๋ก ์ ์งํ๋ Walker ์ค๋ ๋์ ์ซ์๋ฅผ ์ง์ ํ ์ ์์ผ๋ฉฐ
์ด ๊ฐ์ ์ด๋ป๊ฒ ์ค์ ํ๋๋์ ๋ฐ๋ผ ์๋ธ๋ฆฟ ์ปจํ
์ด๋์ ์ ์ฒด ์ฒ๋ฆฌ๋์ด ํฌ๊ฒ ์ํฅ์ ๋ฐ์ต๋๋ค.
์ค์ ์น๋ฅผ ๊ตฌํ๊ธฐ ์ํด ๊ณ ๋ คํด์ผ ํ ์ฌํญ
์ปดํจํฐ์ ์ฐ์ฐ ์ฒ๋ฆฌ๋ CPU๊ฐ ์ํํฉ๋๋ค. ์ฆ, CPU๊ฐ ๊ฐ์ง core์ ์๋งํผ ๊ณ์ฐ ์์
์ ๋์์ ์ฒ๋ฆฌํ ์ ์์ต๋๋ค.
์ด ๋ง์ ์๋ธ๋ฆฟ ์ปจํ
์ด๋๊ฐ CPU ์ฝ์ด ์ ๋ฏธ๋ง์ ์ค๋ ๋๋ฅผ ์ฌ์ฉํ๋ค๋ฉด
1๊ฐ ์ด์์ CPU ์ฝ์ด๋ ์๋ธ๋ฆฟ ์ปจํ
์ด๋๊ฐ ์ฌ์ฉํ์ง ๋ชปํ๋ค๋ ์๋ฏธ์
๋๋ค.
๋ฐ๋ผ์ ์ต๋ ์ค๋ ๋ ์ ์ค์ ์ CPU ์ฝ์ด ์๋ณด๋ค ์์ง ์์์ผ ํฉ๋๋ค.
๋ํ, ๋ณ๋ ฌ ์งํ๋์ด์ผ ํ๋ ์ค๋ ๋์ ์๊ฐ CPU ์ฝ์ด ์๋ณด๋ค ํฐ ๊ฒฝ์ฐ,
๋ชจ๋ ์ค๋ ๋๊ฐ ๋์์ CPU ์ฝ์ด๋ฅผ ์ฌ์ฉํ ์๋ ์์ต๋๋ค.
๋ค์ ๋งํด, ๋ค์์ ์ค๋ ๋๊ฐ ์์์ CPU ์ฝ์ด๋ฅผ ์ด์ฉํ๋ ค๋ฉด,
ํน์ ์๊ฐ์๋ ๋ฐ๋์ ํ๋ ์ด์์ ์ค๋ ๋๊ฐ CPU ์ฝ์ด๋ฅผ ์ ์ ํ์ง ์๊ณ ๋๊ธฐ ์ํ์ ์์ด์ผ ํฉ๋๋ค.