์ฐ๋ฆฌ๋ฅผ ์ํด ExecutorService๋ฅผ ์ค๋นํ๋ newWorkStealingPool ๋ฉ์๋๋ฅผ ์์๋ด ์๋ค .
์ด ์ค๋ ๋ ํ์ ํน๋ณํฉ๋๋ค. ๊ทธ๊ฒ์ ํ๋์ "๋๋์ง" ์์ ์ ์์ด๋์ด๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ํฉ๋๋ค.
์์ ์ ๋๊ธฐํ๊ณ ํ๋ก์ธ์ ๊ฐ์ ๋ถ์ฐ๋ฉ๋๋ค. ๊ทธ๋ฌ๋ ํ๋ก์ธ์๊ฐ ์ฌ์ฉ ์ค์ด๋ฉด ๋ค๋ฅธ ๋ฌด๋ฃ ํ๋ก์ธ์๊ฐ ์์ ์ ํ์ณ ์คํํ ์ ์์ต๋๋ค. ์ด ํ์์ ๋ค์ค ์ค๋ ๋ ์์ฉ ํ๋ก๊ทธ๋จ์์ ์ถฉ๋์ ์ค์ด๊ธฐ ์ํด Java์์ ๋์ ๋์์ต๋๋ค. ํฌํฌ/์กฐ์ธ ํ๋ ์์ํฌ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ํฉ๋๋ค .
ํฌํฌ/์กฐ์ธ
ํฌํฌ/์กฐ์ธ ํ๋ ์์ํฌ ์์ ์์ ์ ์ฌ๊ท์ ์ผ๋ก ๋ถํด๋ฉ๋๋ค. ์ฆ, ํ์ ์์ ์ผ๋ก ๋๋ฉ๋๋ค. ๊ทธ๋ฐ ๋ค์ ํ์ ์์ ์ด ๊ฐ๋ณ์ ์ผ๋ก ์คํ๋๊ณ ํ์ ์์ ์ ๊ฒฐ๊ณผ๊ฐ ๊ฒฐํฉ๋์ด ์๋ ์์ ์ ๊ฒฐ๊ณผ๋ฅผ ํ์ฑํฉ๋๋ค.
fork ๋ฉ์๋๋ ์ผ๋ถ ์ค๋ ๋์์ ๋น๋๊ธฐ์ ์ผ๋ก ์์ ์ ์์ํ๊ณ join ๋ฉ์๋๋ฅผ ์ฌ์ฉ ํ๋ฉด ์ด ์์ ์ด ์๋ฃ๋ ๋๊น์ง ๊ธฐ๋ค๋ฆด ์ ์์ต๋๋ค.
newWorkStealingPool
newWorkStealingPool ๋ฉ์๋ ์๋ ๋ ๊ฐ์ง ๊ตฌํ์ด ์์ต๋๋ค.
public static ExecutorService newWorkStealingPool(int parallelism) {
return new ForkJoinPool
(parallelism,
ForkJoinPool.defaultForkJoinWorkerThreadFactory,
null, true);
}
public static ExecutorService newWorkStealingPool() {
return new ForkJoinPool
(Runtime.getRuntime().availableProcessors(),
ForkJoinPool.defaultForkJoinWorkerThreadFactory,
null, true);
}
์ฒ์๋ถํฐ ๋ด๋ถ์ ์ผ๋ก๋ ThreadPoolExecutor ์์ฑ์๋ฅผ ํธ์ถํ์ง ์๋๋ค๋ ์ ์ ์ ์ํ์ญ์์ค. ์ฌ๊ธฐ์ ์ฐ๋ฆฌ๋ ForkJoinPool ์ํฐํฐ๋ก ์์ ํ๊ณ ์์ต๋๋ค. ThreadPoolExecutor ์ ๋ง์ฐฌ๊ฐ์ง๋ก AbstractExecutorService ์ ๊ตฌํ์ ๋๋ค .
์ฐ๋ฆฌ๋ ์ ํํ ์ ์๋ 2๊ฐ์ง ๋ฐฉ๋ฒ์ด ์์ต๋๋ค. ์ฒซ ๋ฒ์งธ์์ ์ฐ๋ฆฌ๋ ์ฐ๋ฆฌ๊ฐ ๋ณด๊ณ ์ถ์ ๋ณ๋ ฌ ์ฒ๋ฆฌ ์์ค์ ๋ํ๋ ๋๋ค. ์ด ๊ฐ์ ์ง์ ํ์ง ์์ผ๋ฉด ํ์ ๋ณ๋ ฌ ์ฒ๋ฆฌ๋ JVM(Java Virtual Machine)์์ ์ฌ์ฉํ ์ ์๋ ํ๋ก์ธ์ ์ฝ์ด์ ์์ ๊ฐ์ต๋๋ค.
์ค์ ๋ก ์ด๋ป๊ฒ ์๋ํ๋์ง ํ์ ํด์ผ ํฉ๋๋ค.
Collection<Callable<Void>> tasks = new ArrayList<>();
ExecutorService executorService = Executors.newWorkStealingPool(10);
for (int i = 0; i < 10; i++) {
int taskNumber = i;
Callable<Void> callable = () -> {
System.out.println("Processed user request #" + taskNumber + " on thread " + Thread.currentThread().getName());
return null;
};
tasks.add(callable);
}
executorService.invokeAll(tasks);
์์ฒด ์๋ฃ ์ํ๋ฅผ ํ์ํ๋ 10๊ฐ์ ์์ ์ ์์ฑํฉ๋๋ค. ๊ทธ๋ฐ ๋ค์ invokeAll ๋ฉ์๋๋ฅผ ์ฌ์ฉํ์ฌ ๋ชจ๋ ์์ ์ ์์ํฉ๋๋ค.
ํ์ 10๊ฐ ์ค๋ ๋์์ 10๊ฐ์ ์์ ์ ์คํํ ๋์ ๊ฒฐ๊ณผ:
ForkJoinPool-1-worker-5 ์ค๋ ๋์์
์ฒ๋ฆฌ๋ ์ฌ์ฉ์ ์์ฒญ #4 ForkJoinPool-1-worker-8 ์ค๋ ๋์์ ์ฒ๋ฆฌ๋ ์ฌ์ฉ์ ์์ฒญ #7
ForkJoinPool-์์ ์ฒ๋ฆฌ๋ ์ฌ์ฉ์ ์์ฒญ #1 1-worker-2 ์ค๋ ๋
ForkJoinPool-1-worker-3 ์ค๋ ๋์์ ์ฒ๋ฆฌ๋ ์ฌ์ฉ์ ์์ฒญ #2
ForkJoinPool-1-worker-4 ์ค๋ ๋์์
์ฒ๋ฆฌ๋ ์ฌ์ฉ์ ์์ฒญ #3 ForkJoinPool-1-worker-7 ์ค๋ ๋์์ ์ฒ๋ฆฌ๋ ์ฌ์ฉ์ ์์ฒญ #6
์ฒ๋ฆฌ๋ ์ฌ์ฉ์ ForkJoinPool-1-worker-1 ์ค๋ ๋์์ ์์ฒญ #0
ForkJoinPool-1-worker-6 ์ค๋ ๋์์ ์ฒ๋ฆฌ๋ ์ฌ์ฉ์ ์์ฒญ #5 ForkJoinPool-
1-worker-9 ์ค๋ ๋์์ ์ฒ๋ฆฌ๋ ์ฌ์ฉ์ ์์ฒญ #8
๋๊ธฐ์ด์ด ํ์ฑ๋ ํ ์ค๋ ๋๊ฐ ์คํ์ ์ํด ์์ ์ ์ํํ๋ ๊ฒ์ ๋ณผ ์ ์์ต๋๋ค. ๋ํ 10๊ฐ์ ์ค๋ ๋ ํ์์ 20๊ฐ์ ์์ ์ด ์ด๋ป๊ฒ ๋ถ์ฐ๋๋์ง ํ์ธํ ์ ์์ต๋๋ค.
์์ฒญ #3 ForkJoinPool-1-worker-8 ์ค๋ ๋์์
์ฒ๋ฆฌ๋ ์ฌ์ฉ์ ์์ฒญ #7 ForkJoinPool-1-worker-3 ์ค๋ ๋์์ ์ฒ๋ฆฌ๋ ์ฌ์ฉ์ ์์ฒญ #2
ForkJoinPool-์์ ์ฒ๋ฆฌ๋ ์ฌ์ฉ์ ์์ฒญ #4 1-worker-5 ์ค๋ ๋
ForkJoinPool-1-worker-2 ์ค๋ ๋์์ ์ฒ๋ฆฌ๋ ์ฌ์ฉ์ ์์ฒญ #1
ForkJoinPool-1-worker-6 ์ค๋ ๋์์
์ฒ๋ฆฌ๋ ์ฌ์ฉ์ ์์ฒญ #5 ForkJoinPool-1-worker-9 ์ค๋ ๋์์ ์ฒ๋ฆฌ๋ ์ฌ์ฉ์ ์์ฒญ #8
์ฒ๋ฆฌ๋ ์ฌ์ฉ์ ForkJoinPool-1-worker-10 ์ค๋ ๋์์ ์์ฒญ #9
ForkJoinPool-1-worker-1 ์ค๋ ๋์์ ์ฒ๋ฆฌ๋ ์ฌ์ฉ์ ์์ฒญ #0
ForkJoinPool-1-worker-7 ์ค๋ ๋์์ ์ฒ๋ฆฌ๋ ์ฌ์ฉ์ ์์ฒญ #6
ForkJoinPool-1-์์ ์ฒ๋ฆฌ๋ ์ฌ์ฉ์ ์์ฒญ #10 ์์ ์-9 ์ค๋ ๋
ForkJoinPool-1-worker-1 ์ค๋ ๋์์ ์ฒ๋ฆฌ๋ ์ฌ์ฉ์ ์์ฒญ #12
ForkJoinPool-1-worker-8 ์ค๋ ๋์์
์ฒ๋ฆฌ๋ ์ฌ์ฉ์ ์์ฒญ #13 ForkJoinPool-1-worker-6 ์ค๋ ๋์์ ์ฒ๋ฆฌ๋ ์ฌ์ฉ์ ์์ฒญ #11
ForkJoinPool-์์ ์ฒ๋ฆฌ๋ ์ฌ์ฉ์ ์์ฒญ #15 1-worker-8 ์ค๋ ๋
ForkJoinPool-1-worker-1 ์ค๋ ๋์์ ์ฒ๋ฆฌ๋ ์ฌ์ฉ์ ์์ฒญ #14
ForkJoinPool-1-worker-6 ์ค๋ ๋์์
์ฒ๋ฆฌ๋ ์ฌ์ฉ์ ์์ฒญ #17 ForkJoinPool-1-worker-7 ์ค๋ ๋์์ ์ฒ๋ฆฌ๋ ์ฌ์ฉ์ ์์ฒญ #16
์ฒ๋ฆฌ๋ ์ฌ์ฉ์ ForkJoinPool-1-worker-6 ์ค๋ ๋์ ์์ฒญ #19
ForkJoinPool-1-worker-1 ์ค๋ ๋์ ์ฒ๋ฆฌ๋ ์ฌ์ฉ์ ์์ฒญ #18
์ถ๋ ฅ์์ ์ผ๋ถ ์ค๋ ๋๋ ์ฌ๋ฌ ์์ ( ForkJoinPool-1-worker-6 ์๋ฃ 4 ์์ ์๋ฃ)์ ๊ด๋ฆฌํ๋ ๋ฐ๋ฉด ์ผ๋ถ ์ค๋ ๋๋ ํ๋๋ง ์๋ฃ( ForkJoinPool-1-worker-2 )ํ๋ ๊ฒ์ ๋ณผ ์ ์์ต๋๋ค. call ๋ฉ์๋ ๊ตฌํ์ 1์ด ์ง์ฐ์ด ์ถ๊ฐ๋๋ฉด ๊ทธ๋ฆผ์ด ๋ฐ๋๋๋ค.
Callable<Void> callable = () -> {
System.out.println("Processed user request #" + taskNumber + " on thread " + Thread.currentThread().getName());
TimeUnit.SECONDS.sleep(1);
return null;
};
์คํ์ ์ํด ๋ค๋ฅธ ์ปดํจํฐ์์ ๋์ผํ ์ฝ๋๋ฅผ ์คํํด ๋ณด๊ฒ ์ต๋๋ค. ๊ฒฐ๊ณผ ์ถ๋ ฅ:
ForkJoinPool-1-worker-31 ์ค๋ ๋์์
์ฒ๋ฆฌ๋ ์ฌ์ฉ์ ์์ฒญ #7 ForkJoinPool-1-worker-27 ์ค๋ ๋์์ ์ฒ๋ฆฌ๋ ์ฌ์ฉ์ ์์ฒญ #4
ForkJoinPool-์์ ์ฒ๋ฆฌ๋ ์ฌ์ฉ์ ์์ฒญ #5 1-worker-13 ์ค๋ ๋
ForkJoinPool-1-worker-19 ์ค๋ ๋์์ ์ฒ๋ฆฌ๋ ์ฌ์ฉ์ ์์ฒญ #0
ForkJoinPool-1-worker-3 ์ค๋ ๋์์
์ฒ๋ฆฌ๋ ์ฌ์ฉ์ ์์ฒญ #8 ForkJoinPool-1-worker-21 ์ค๋ ๋์์ ์ฒ๋ฆฌ๋ ์ฌ์ฉ์ ์์ฒญ #9
์ฒ๋ฆฌ๋ ์ฌ์ฉ์ ForkJoinPool-1-worker-17 ์ค๋ ๋์์ ์์ฒญ #6
ForkJoinPool-1-worker-9 ์ค๋ ๋์์ ์ฒ๋ฆฌ๋ ์ฌ์ฉ์ ์์ฒญ #3
ForkJoinPool-1-worker-5 ์ค๋ ๋์์ ์ฒ๋ฆฌ๋ ์ฌ์ฉ์ ์์ฒญ #1
ForkJoinPool-1-์์ ์ฒ๋ฆฌ๋ ์ฌ์ฉ์ ์์ฒญ #12 ์์ ์-23 ์ค๋ ๋
ForkJoinPool-1-worker-19 ์ค๋ ๋์์ ์ฒ๋ฆฌ๋ ์ฌ์ฉ์ ์์ฒญ #15
ForkJoinPool-1-worker-27 ์ค๋ ๋์์
์ฒ๋ฆฌ๋ ์ฌ์ฉ์ ์์ฒญ #14 ForkJoinPool-1-worker-3 ์ค๋ ๋์์ ์ฒ๋ฆฌ๋ ์ฌ์ฉ์ ์์ฒญ #11
ForkJoinPool-์์ ์ฒ๋ฆฌ๋ ์ฌ์ฉ์ ์์ฒญ #13 1-worker-13 ์ค๋ ๋
ForkJoinPool-1-worker-31 ์ค๋ ๋์์ ์ฒ๋ฆฌ๋ ์ฌ์ฉ์ ์์ฒญ #10
ForkJoinPool-1-worker-5 ์ค๋ ๋์์
์ฒ๋ฆฌ๋ ์ฌ์ฉ์ ์์ฒญ #18 ForkJoinPool-1-worker-9 ์ค๋ ๋์์ ์ฒ๋ฆฌ๋ ์ฌ์ฉ์ ์์ฒญ #16
์ฒ๋ฆฌ๋ ์ฌ์ฉ์ ForkJoinPool-1-worker-21 ์ค๋ ๋์ ์์ฒญ #17
ForkJoinPool-1-worker-17 ์ค๋ ๋์ ์ฒ๋ฆฌ๋ ์ฌ์ฉ์ ์์ฒญ #19
์ด ์ถ๋ ฅ์์ โโํ์ ์ค๋ ๋๋ฅผ "์์ฒญ"ํ ๊ฒ์ด ์ฃผ๋ชฉํ ๋งํฉ๋๋ค. ๋ํ ์์ ์ ์ค๋ ๋์ ์ด๋ฆ์ 1์์ 10๊น์ง๊ฐ ์๋๋ผ ๋๋๋ก 10๋ณด๋ค ๋์ต๋๋ค. ๊ณ ์ ํ ์ด๋ฆ์ ๋ณด๋ฉด ์ค์ ๋ก 10๋ช ์ ์ผ๊พผ์ด ์์์ ์ ์ ์์ต๋๋ค(3, 5, 9, 13, 17, 19, 21, 23, 27 ๋ฐ 31). ์ ์ด๋ฐ ์ผ์ด ์ผ์ด ๋ฌ๋์ง ๋ฌป๋ ๊ฒ์ด ํฉ๋ฆฌ์ ์ ๋๊น? ์งํ ์ํฉ์ ์ดํดํ์ง ๋ชปํ ๋๋ง๋ค ๋๋ฒ๊ฑฐ๋ฅผ ์ฌ์ฉํ์ญ์์ค.
์ด๊ฒ์ด ์ฐ๋ฆฌ๊ฐ ํ ์ผ์ ๋๋ค. ์บ์คํ ํ์์งํ์ ์๋น์คForkJoinPool ์ ๋ํ ๊ฐ์ฒด :
final ForkJoinPool forkJoinPool = (ForkJoinPool) executorService;
invokeAll ๋ฉ์๋ ๋ฅผ ํธ์ถํ ํ Evaluate Expression ์์ ์ ์ฌ์ฉํ์ฌ ์ด ๊ฐ์ฒด๋ฅผ ๊ฒ์ฌํฉ๋๋ค . ์ด๋ ๊ฒ ํ๋ ค๋ฉด invokeAll ๋ฉ์๋ ๋ค์ ๋น sout๊ณผ ๊ฐ์ ๋ฌธ์ ์ถ๊ฐํ๊ณ ์ค๋จ์ ์ ์ค์ ํฉ๋๋ค.
ํ์ 10๊ฐ์ ์ค๋ ๋๊ฐ ์์ง๋ง ์์ ์ ์ค๋ ๋ ๋ฐฐ์ด์ ํฌ๊ธฐ๋ 32๊ฐ์์ ์ ์ ์์ต๋๋ค. ์ด์ํ์ง๋ง ๊ด์ฐฎ์ต๋๋ค. ๊ณ์ ํ์. ํ์ ์์ฑํ ๋ ๋ณ๋ ฌ ์ฒ๋ฆฌ ์์ค์ 32 ์ด์, ์๋ฅผ ๋ค์ด 40์ผ๋ก ์ค์ ํด ๋ด ์๋ค.
ExecutorService executorService = Executors.newWorkStealingPool(40);
๋๋ฒ๊ฑฐ์์ ์ดํด๋ณด๊ฒ ์ต๋๋ค.๋ค์ forkJoinPool ๊ฐ์ฒด.
์ด์ ์์ ์ ์ค๋ ๋ ๋ฐฐ์ด์ ํฌ๊ธฐ๋ 128์ ๋๋ค. ์ด๊ฒ์ด JVM์ ๋ด๋ถ ์ต์ ํ ์ค ํ๋๋ผ๊ณ ๊ฐ์ ํ ์ ์์ต๋๋ค. JDK(openjdk-14)์ ์ฝ๋์์ ์ฐพ์๋ด ์๋ค.
์์ํ ๋๋ก ์์ ์ ์ค๋ ๋ ๋ฐฐ์ด์ ํฌ๊ธฐ๋ ๋ณ๋ ฌ๋ ๊ฐ์ ๋ํด ๋นํธ ๋จ์ ์กฐ์์ ์ํํ์ฌ ๊ณ์ฐ๋ฉ๋๋ค. ์ฌ๊ธฐ์ ์ ํํ ๋ฌด์จ ์ผ์ด ์ผ์ด๋๊ณ ์๋์ง ์์๋ด๋ ค๊ณ ๋ ธ๋ ฅํ ํ์๊ฐ ์์ต๋๋ค. ๊ทธ๋ฌํ ์ต์ ํ๊ฐ ์กด์ฌํ๋ค๋ ์ฌ์ค์ ์๋ ๊ฒ๋ง์ผ๋ก๋ ์ถฉ๋ถํฉ๋๋ค.
์ฐ๋ฆฌ ์์ ์ ๋ ๋ค๋ฅธ ํฅ๋ฏธ๋ก์ด ์ธก๋ฉด์ invokeAll ๋ฉ์๋ ์ ์ฌ์ฉ์ ๋๋ค . invokeAll ๋ฉ์๋๊ฐ ๊ฒฐ๊ณผ๋ฅผ ๋ฐํํ๊ฑฐ๋ ๊ฐ ์์ ์ ๊ฒฐ๊ณผ๋ฅผ ์ฐพ์ ์ ์๋ ๊ฒฐ๊ณผ ๋ชฉ๋ก(์ด ๊ฒฝ์ฐ List <Future<Void>>)์ ๋ฐํํ ์ ์๋ค๋ ์ ์ ์ฃผ๋ชฉํ ๊ฐ์น๊ฐ ์์ต๋๋ค .
var results = executorService.invokeAll(tasks);
for (Future<Void> result : results) {
// Process the task's result
}
์ด ํน๋ณํ ์ข ๋ฅ์ ์๋น์ค ๋ฐ ์ค๋ ๋ ํ์ ์์ธก ๊ฐ๋ฅํ๊ฑฐ๋ ์ต์ํ ์์์ ์ธ ์์ค์ ๋์์ฑ์ ๊ฐ์ง ์์ ์์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
GO TO FULL VERSION