๋‹ค์ค‘ ์Šค๋ ˆ๋“œ ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์„ ๊ฐœ๋ฐœํ•  ๋•Œ ์ผ๋ฐ˜์ ์œผ๋กœ ์Šค๋ ˆ๋“œ ์ž‘์—… ๊ตฌ์„ฑ์„ ์ฒ˜๋ฆฌํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์ด ํด์ˆ˜๋ก ๋‹ค์ค‘ ์Šค๋ ˆ๋“œ ์ž‘์—…์— ํ•„์š”ํ•œ ์Šค๋ ˆ๋“œ๊ฐ€ ๋งŽ์„์ˆ˜๋ก์‹คํ–‰ ๊ฐ€๋Šฅ์šฐ๋ฆฌ๊ฐ€ ๋งŒ๋“œ๋Š” ๊ฐ์ฒด.

์—ฌ๊ธฐ์—์„œ Java๋กœ ์Šค๋ ˆ๋“œ๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ์€ ๋‹ค์†Œ ๋น„์šฉ์ด ๋งŽ์ด ๋“œ๋Š” ์ž‘์—…์ด๋ผ๋Š” ์ ์— ์œ ์˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๊ธฐ ์œ„ํ•ด ๋งค๋ฒˆ ์Šค๋ ˆ๋“œ์˜ ์ƒˆ ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•˜๋ฉด ์„ฑ๋Šฅ์— ํฐ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜๊ณ  ๊ฒฐ๊ณผ์ ์œผ๋กœ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์ƒํƒœ์— ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

์—ฌ๊ธฐ์„œ ์Šค๋ ˆ๋“œ ํ’€ ๊ณผ ThreadPoolExecutor๊ฐ€ ๋„์›€์ด ๋ฉ๋‹ˆ๋‹ค.

์Šค๋ ˆ๋“œ ํ’€์€ ๋ฏธ๋ฆฌ ์ดˆ๊ธฐํ™”๋œ ์Šค๋ ˆ๋“œ ์ง‘ํ•ฉ์ž…๋‹ˆ๋‹ค. ํฌ๊ธฐ๋Š” ๊ณ ์ •๋˜๊ฑฐ๋‚˜ ๊ฐ€๋ณ€์ ์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์Šค๋ ˆ๋“œ๋ณด๋‹ค ์ž‘์—…์ด ๋งŽ์œผ๋ฉด ์ž‘์—…์ด ์ž‘์—… ๋Œ€๊ธฐ์—ด์—์„œ ๋Œ€๊ธฐํ•ฉ๋‹ˆ๋‹ค. ํ’€์˜ N๋ฒˆ์งธ ์Šค๋ ˆ๋“œ๋Š” ๋Œ€๊ธฐ์—ด์—์„œ ์ž‘์—…์„ ๊ฐ€์ ธ์˜ค๊ณ  ์ž‘์—…์ด ์™„๋ฃŒ๋œ ํ›„ ์Šค๋ ˆ๋“œ๋Š” ๋Œ€๊ธฐ์—ด์—์„œ ์ƒˆ ์ž‘์—…์„ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค. ๋Œ€๊ธฐ์—ด์˜ ๋ชจ๋“  ์ž‘์—…์ด ์‹คํ–‰๋˜๋ฉด ์Šค๋ ˆ๋“œ๋Š” ํ™œ์„ฑ ์ƒํƒœ๋ฅผ ์œ ์ง€ํ•˜๊ณ  ์ƒˆ ์ž‘์—…์„ ๊ธฐ๋‹ค๋ฆฝ๋‹ˆ๋‹ค. ์ƒˆ ์ž‘์—…์ด ๋‚˜ํƒ€๋‚˜๋ฉด ์Šค๋ ˆ๋“œ๋„ ํ•ด๋‹น ์ž‘์—…์„ ์‹คํ–‰ํ•˜๊ธฐ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค.

ThreadPoolExecutor

Java 5๋ถ€ํ„ฐ Executor ํ”„๋ ˆ์ž„์›Œํฌ๋Š” ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋”ฉ ์†”๋ฃจ์…˜์„ ์–ป์—ˆ์Šต๋‹ˆ๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ ๋งŽ์€ ๊ตฌ์„ฑ ์š”์†Œ๊ฐ€ ์žˆ์œผ๋ฉฐ ๊ทธ ๋ชฉ์ ์€ ๋Œ€๊ธฐ์—ด๊ณผ ์Šค๋ ˆ๋“œ ํ’€์„ ํšจ์œจ์ ์œผ๋กœ ๊ด€๋ฆฌํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์ฃผ์š” ์ธํ„ฐํŽ˜์ด์Šค๋Š” Executor ๋ฐ ExecutorService ์ž…๋‹ˆ๋‹ค .

Executor ๋Š” ๋‹จ์ผ void execute(Runnable runnable) ๋ฉ”์„œ๋“œ๊ฐ€ ์žˆ๋Š” ์ธํ„ฐํŽ˜์ด์Šค์ž…๋‹ˆ๋‹ค.

์ด ๋ฉ”์„œ๋“œ์˜ ๊ตฌํ˜„์— ์ž‘์—…์„ ์ „๋‹ฌํ•  ๋•Œ ๋‚˜์ค‘์— ๋น„๋™๊ธฐ์ ์œผ๋กœ ์‹คํ–‰๋œ๋‹ค๋Š” ์ ์„ ์•Œ์•„๋‘์„ธ์š”.

ExecutorService โ€” Executor ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํ™•์žฅํ•˜์—ฌ ์ž‘์—… ์‹คํ–‰ ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•˜๋Š” ์ธํ„ฐํŽ˜์ด์Šค์ž…๋‹ˆ๋‹ค. ๋˜ํ•œ ์‹คํ–‰ ์ค‘์ธ ์ž‘์—…์„ ์ค‘๋‹จํ•˜๊ณ  ์Šค๋ ˆ๋“œ ํ’€์„ ์ข…๋ฃŒํ•˜๋Š” ๋ฉ”์„œ๋“œ๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

ThreadPoolExecutor๋Š” Executor ๋ฐ ExecutorService ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•˜๊ณ  ์ž‘์—… ์ƒ์„ฑ๊ณผ ์ž‘์—… ์‹คํ–‰์„ ๋ถ„๋ฆฌํ•ฉ๋‹ˆ๋‹ค. Runnable ๊ฐ์ฒด๋ฅผ ๊ตฌํ˜„ํ•˜๊ณ  ์‹คํ–‰๊ธฐ๋กœ ๋ณด๋‚ด์•ผํ•ฉ๋‹ˆ๋‹ค๊ทธ๋Ÿฐ ๋‹ค์Œ ThreadPoolExecutor ๋Š” ์ž‘์—… ์‹คํ–‰๊ณผ ์Šค๋ ˆ๋“œ ์ƒ์„ฑ ๋ฐ ์ž‘์—…์„ ๋‹ด๋‹นํ•ฉ๋‹ˆ๋‹ค.

์‹คํ–‰์„ ์œ„ํ•ด ์ž‘์—…์„ ๋ณด๋‚ธ ํ›„ ํ’€์˜ ๊ธฐ์กด ์Šค๋ ˆ๋“œ๊ฐ€ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์„ฑ๋Šฅ์ด ํ–ฅ์ƒ๋ฉ๋‹ˆ๋‹ค. ์ƒˆ ์Šค๋ ˆ๋“œ๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์ดˆ๊ธฐํ™”ํ•˜๋Š” ๋ฐ ๋ฆฌ์†Œ์Šค๋ฅผ ๋‚ญ๋น„ํ•˜๋Š” ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•œ ๋‹ค์Œ ์Šค๋ ˆ๋“œ ์ž‘์—…์ด ์™„๋ฃŒ๋˜๋ฉด ๋‹ค์‹œ ๊ฐ€๋น„์ง€ ์ˆ˜์ง‘์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

ThreadPoolExecutor ์—๋Š” 4๊ฐœ์˜ ์ƒ์„ฑ์ž๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.


ThreadPoolExecutor(
int corePoolSize,
int maximumPoolSize,
long keepAliveTime, 
TimeUnit unit, 
BlockingQueue<Runnable> workQueue)
    

ThreadPoolExecutor(
int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
RejectedExecutionHandler handler)
    

ThreadPoolExecutor(
int corePoolSize,
int maximumPoolSize,
long keepAliveTime, 
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory)
    

ThreadPoolExecutor(
int corePoolSize,
int maximumPoolSize,
long keepAliveTime, 
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory, 
RejectedExecutionHandler handler)
    

ThreadPoolExecutor ์ƒ์„ฑ์ž ์—๋Š” ๋‹ค์Œ ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

corePoolSize ์ด ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” ์‹คํ–‰๊ธฐ ์„œ๋น„์Šค๊ฐ€ ์‹œ์ž‘๋  ๋•Œ ์ค€๋น„(์‹œ์ž‘)๋  ์Šค๋ ˆ๋“œ ์ˆ˜๋ฅผ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.
์ตœ๋Œ€ ํ’€ ํฌ๊ธฐ ์‹คํ–‰๊ธฐ ์„œ๋น„์Šค๊ฐ€ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋Š” ์ตœ๋Œ€ ์Šค๋ ˆ๋“œ ์ˆ˜์ž…๋‹ˆ๋‹ค.
keepAliveTime ์Šค๋ ˆ๋“œ ์ˆ˜๊ฐ€ ๋‹ค์Œ๋ณด๋‹ค ํฐ ๊ฒฝ์šฐ ํ•ด์ œ๋œ ์Šค๋ ˆ๋“œ๊ฐ€ ์†Œ๋ฉธ๋˜๊ธฐ ์ „์— ๊ณ„์† ์œ ์ง€๋˜๋Š” ์‹œ๊ฐ„corePoolSize. ์‹œ๊ฐ„ ๋‹จ์œ„๋Š” ๋‹ค์Œ ๋งค๊ฐœ๋ณ€์ˆ˜์— ์ง€์ •๋ฉ๋‹ˆ๋‹ค.
๋‹จ์œ„ ์‹œ๊ฐ„ ๋‹จ์œ„(์‹œ, ๋ถ„, ์ดˆ, ๋ฐ€๋ฆฌ์ดˆ ๋“ฑ).
์ž‘์—… ๋Œ€๊ธฐ์—ด ์ž‘์—… ๋Œ€๊ธฐ์—ด ๊ตฌํ˜„.
๋งค๋‹ˆ์ € ์™„๋ฃŒํ•  ์ˆ˜ ์—†๋Š” ์ž‘์—…์— ๋Œ€ํ•œ ํ•ธ๋“ค๋Ÿฌ์ž…๋‹ˆ๋‹ค.
์Šค๋ ˆ๋“œํŒฉํ† ๋ฆฌ ์š”์ฒญ ์‹œ ์ƒˆ ์Šค๋ ˆ๋“œ๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๊ฐœ์ฒด์ž…๋‹ˆ๋‹ค. ์Šค๋ ˆ๋“œ ํŒฉํ† ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ƒˆ๋กœ์šด ์Šค๋ ˆ๋“œ ํ•˜๋“œ์›จ์–ด๋ฅผ ๋…๋ฆฝ์ ์œผ๋กœ ํ˜ธ์ถœํ•˜์—ฌ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ํŠน์ˆ˜ ์Šค๋ ˆ๋“œ ํ•˜์œ„ ํด๋ž˜์Šค, ์šฐ์„  ์ˆœ์œ„ ๋“ฑ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ThreadPoolExecutor ์ƒ์„ฑ

Executors ์œ ํ‹ธ๋ฆฌํ‹ฐ ํด๋ž˜์Šค ๋Š” ThreadPoolExecutor ์ƒ์„ฑ์„ ๋‹จ์ˆœํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค . ์ด ์œ ํ‹ธ๋ฆฌํ‹ฐ ํด๋ž˜์Šค์˜ ๋ฉ”์„œ๋“œ๋Š” ๋‹ค์Œ์„ ์ค€๋น„ํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋ฉ๋‹ˆ๋‹ค.ThreadPoolExecutor๋ฌผ์ฒด.

newFixedThreadPool โ€” ๊ณ ์ •๋œ ์ˆ˜์˜ ์Šค๋ ˆ๋“œ๋ฅผ ์žฌ์‚ฌ์šฉํ•˜์—ฌ ์›ํ•˜๋Š” ์ˆ˜์˜ ์ž‘์—…์„ ์‹คํ–‰ํ•˜๋Š” ์Šค๋ ˆ๋“œ ํ’€์„ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

ExecutorService executor = Executors.newFixedThreadPool(10);
                    
newWorkStealingPool โ€” ์Šค๋ ˆ๋“œ ์ˆ˜๊ฐ€ JVM์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ํ”„๋กœ์„ธ์„œ ์ฝ”์–ด ์ˆ˜์™€ ๋™์ผํ•œ ์Šค๋ ˆ๋“œ ํ’€์„ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ๊ธฐ๋ณธ ๋™์‹œ์„ฑ ์ˆ˜์ค€์€ 1์ž…๋‹ˆ๋‹ค. ์ฆ‰, JVM์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” CPU ์ฝ”์–ด๋งŒํผ ๋งŽ์€ ์Šค๋ ˆ๋“œ๊ฐ€ ํ’€์— ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค. ๋™์‹œ์„ฑ ์ˆ˜์ค€์ด 4์ด๋ฉด ์ฝ”์–ด ์ˆ˜ ๋Œ€์‹  ์ „๋‹ฌ๋œ ๊ฐ’์ด ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

ExecutorService executor = Executors.newWorkStealingPool(4);
                    
newSingleThreadExecutor โ€” ๋ชจ๋“  ์ž‘์—…์„ ์‹คํ–‰ํ•˜๋Š” ๋‹จ์ผ ์Šค๋ ˆ๋“œ๋กœ ํ’€์„ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

ExecutorService executor = Executors.newSingleThreadExecutor();
                    
newCachedThreadPool โ€” ํ•„์š”์— ๋”ฐ๋ผ ์ƒˆ ์Šค๋ ˆ๋“œ๋ฅผ ์ƒ์„ฑํ•˜์ง€๋งŒ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ๊ฒฝ์šฐ ์ด์ „์— ์ƒ์„ฑ๋œ ์Šค๋ ˆ๋“œ๋ฅผ ์žฌ์‚ฌ์šฉํ•˜๋Š” ์Šค๋ ˆ๋“œ ํ’€์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

ExecutorService executor = Executors.newCachedThreadPool();
                    
newScheduledThreadPool โ€” ์ง€์ •๋œ ์ง€์—ฐ ํ›„ ๋˜๋Š” ์ฃผ๊ธฐ์ ์œผ๋กœ ์‹คํ–‰ํ•  ๋ช…๋ น์„ ์˜ˆ์•ฝํ•  ์ˆ˜ ์žˆ๋Š” ์Šค๋ ˆ๋“œ ํ’€์„ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

ScheduledExecutorService executor = Executors.newScheduledThreadPool(10);
                    

๋‹ค์Œ ๋‹จ์›์—์„œ๋Š” ๊ฐ ์œ ํ˜•์˜ ํ’€์„ ๊ณ ๋ คํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.