๐ป Programming/Java
[Java] ์๋ฐ ThreadPoolTaskExecutor๋ฅผ ์ด์ฉํ์ฌ ๋น๋๊ธฐ ์ฒ๋ฆฌํ๊ธฐ(๋ฉํฐ์ฐ๋ ๋)
async(๋น๋๊ธฐ) ์ฒ๋ฆฌ๋ฅผ ์ํ ThreadPoolTaskExecutor
ThreadPoolTaskExecutor๋ฅผ ์ด์ฉํ์ฌ ๋น๋๊ธฐ์ฒ๋ฆฌํ๋ ๋ฐฉ๋ฒ์ ์์๋ณด๊ฒ ์ต๋๋ค.
ThreadPoolTaskExecutor๋ ์คํ๋ง์์ ์ ๊ณตํด์ฃผ๋ ํด๋์ค๋ก org.springframework.scheduling.concurrent ํจํค์ง์ ์ํด์์ต๋๋ค.
์์ฑ์๋ ๊ธฐ๋ณธ์์ฑ์ ํ๋๋ง ์กด์ฌํฉ๋๋ค. ์ด๋ฆ์์ ์ ์ ์๋ฏ์ด ์ฐ๋ ๋ํ์ ์ด์ฉํ์ฌ ๋ฉํฐ์ฐ๋ ๋ ๊ตฌํ์ ์ฝ๊ฒ ํด์ฃผ๋ ํด๋์ค์ ๋๋ค.
๊ทธ๋ผ ์ด๋ป๊ฒ ์ฌ์ฉํ๋์ง ์ดํด๋ณด๊ฒ ์ต๋๋ค.
public static void main(String[] args) {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.initialize();
}
ThreadPoolTaskExecutor ๋ฅผ ์์ฑํ๊ณ ์ฌ์ฉํ ์ ์๋๋ก initialize()๋ฅผ ํธ์ถํ์ต๋๋ค. ์๋๋ฉด ์ด๋์ ๋ผ์ด์ฆํ๊ธฐ ์ ์๋ executor๋ฅผ ์ฌ์ฉ์ ํ ์ ์๊ธฐ ๋๋ฌธ์ ๋๋ค. ๋ง์ฝ ์ด๋์ ๋ผ์ด์ฆ ํ๊ธฐ ์ ์ ์ฌ์ฉํ๋ ค๊ณ ํ๋ค๋ฉด ์๋์ ๊ฐ์ ์ค๋ฅ ๋ฉ์์ง๋ฅผ ๋ณด๊ฒ ๋ฉ๋๋ค.
Exception in thread "main" java.lang.IllegalStateException: ThreadPoolTaskExecutor not initialized
๊ทธ๋ผ ์ด์ ์๋์ฒ๋ผ ์ฝ๋๋ฅผ ์ข ๋ ์ถ๊ฐํ ๋ค ์ค์ ๋ก ์ฐ๋ ๋๋ฅผ ์คํ์์ผ ๋ณด๊ฒ ์ต๋๋ค.
public static void main(String[] args) {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.initialize();
log.info("executing threads....");
Runnable r = () -> {
try {
log.info(Thread.currentThread().getName() + ", Now sleeping 10 seconds...");
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
};
for (int i = 0; i < 10; i++) {
executor.execute(r);
}
}
์ถ๋ ฅ ๊ฒฐ๊ณผ๋ฅผ ํ๋ฒ ๋ณผ๊น์?
07:42:09.450 [main] INFO com.keichee.test.service.TestService - executing threads....
07:42:09.460 [ThreadPoolTaskExecutor-1] INFO com.keichee.test.service.TestService - ThreadPoolTaskExecutor-1, Now sleeping 10 seconds...
07:42:19.464 [ThreadPoolTaskExecutor-1] INFO com.keichee.test.service.TestService - ThreadPoolTaskExecutor-1, Now sleeping 10 seconds...
07:42:29.465 [ThreadPoolTaskExecutor-1] INFO com.keichee.test.service.TestService - ThreadPoolTaskExecutor-1, Now sleeping 10 seconds...
07:42:39.470 [ThreadPoolTaskExecutor-1] INFO com.keichee.test.service.TestService - ThreadPoolTaskExecutor-1, Now sleeping 10 seconds...
07:42:49.472 [ThreadPoolTaskExecutor-1] INFO com.keichee.test.service.TestService - ThreadPoolTaskExecutor-1, Now sleeping 10 seconds...
07:42:59.477 [ThreadPoolTaskExecutor-1] INFO com.keichee.test.service.TestService - ThreadPoolTaskExecutor-1, Now sleeping 10 seconds...
07:43:09.483 [ThreadPoolTaskExecutor-1] INFO com.keichee.test.service.TestService - ThreadPoolTaskExecutor-1, Now sleeping 10 seconds...
07:43:19.489 [ThreadPoolTaskExecutor-1] INFO com.keichee.test.service.TestService - ThreadPoolTaskExecutor-1, Now sleeping 10 seconds...
07:43:29.491 [ThreadPoolTaskExecutor-1] INFO com.keichee.test.service.TestService - ThreadPoolTaskExecutor-1, Now sleeping 10 seconds...
07:43:39.496 [ThreadPoolTaskExecutor-1] INFO com.keichee.test.service.TestService - ThreadPoolTaskExecutor-1, Now sleeping 10 seconds...
๋ก๊ทธ๊ฐ ์ถ๋ ฅ๋ ์๊ฐ์ ๋ณด๋ฉด 10์ด๋ง๋ค ์ถ๋ ฅ์ด ๋๊ณ ์๊ณ ์ฐ๋ ๋๋ ThreadPoolTaskExecutor-1 ํ๋๊ฐ ๋ชจ๋ ์ฒ๋ฆฌํ ๊ฒ์ ์ ์ ์์ต๋๋ค. ์ฆ, ์ง๊ธ ์ ์ฝ๋๋ ๋ฉํฐ์ฐ๋ ๋๋ก ๋์๊ฐ๊ฒ ์๋๋ ์๊ธฐ์ฃ . ThreadPoolTaskExecutor๋ ๋ช ๊ฐ์ง ์ค์ ๊ฐ๋ค์ ๊ฐ์ง๊ณ ์์ต๋๋ค. ๊ทธ ์ค corePoolSize ๊ฐ์ด ๋์์ ์คํํ ์ฐ๋ ๋์ ๊ฐ์๋ฅผ ์๋ฏธํ๋๋ฐ ์ด ์ค์ ์ default ๊ฐ์ด 1๋ก ์ธํ ๋์ด ์๊ธฐ ๋๋ฌธ์ ์ ์ฒ๋ผ corePoolSize ์ค์ ์์ด ๊ทธ๋๋ก ์ฌ์ฉํ๋ฉด ์ฑ๊ธ์ฐ๋ ๋๋ก ๋์๊ฐ๊ฒ ๋ฉ๋๋ค.
์ค์ ๊ฐ
๊ทธ๋ผ ์ค์ ๊ฐ๋ค์ ์ด๋ค ๊ฒ๋ค์ด ์๋์ง ๊ทธ๊ฒ๋ค์ด ์๋ฏธํ๋๊ฒ ๋ฌด์์ธ์ง setter ๋ฉ์๋๋ฅผ ๊ธฐ์ค์ผ๋ก ์ค์ํ ๊ฐ๋ค๋ง ํ๋ฒ ์ดํด๋ณด๊ณ ๋์ด๊ฐ๊ฒ ์ต๋๋ค.
๋ฉ์๋ |
์ค๋ช |
๊ธฐ๋ณธ๊ฐ |
setCorePoolSize |
corePoolSize ๊ฐ์ ์ค์ ํจ. corePoolSize๋ ๋์์ ์คํ์ํฌ ์ฐ๋ ๋์ ๊ฐ์๋ฅผ ์๋ฏธํจ |
1 |
setAllowCoreThreadTimeOut |
์ฝ์ด ์ฐ๋ ๋์ ํ์์์์ ํ์ฉํ ๊ฒ์ธ์ง์ ๋ํ ์ธํฐ ๋ฉ์๋. true๋ก ์ค์ ํ ๊ฒฝ์ฐ ์ฝ์ด ์ฐ๋ ๋๋ฅผ 10์ผ๋ก ์ค์ ํ์ด๋ ์ผ์ ์๊ฐ(keepAliveSeconds)์ด ์ง๋๋ฉด ์ฝ์ด ์ฐ๋ ๋ ๊ฐ์๊ฐ ์ค์ด๋ฆ. |
false |
setKeepAliveSeconds |
์ฝ์ด ์ฐ๋ ๋ ํ์์์์ ํ์ฉํ์ ๊ฒฝ์ฐ ์ฌ์ฉ๋๋ ์ค์ ๊ฐ์ผ๋ก, ์ฌ๊ธฐ ์ค์ ๋ ์๊ฐ์ด ์ง๋ ๋๊น์ง ์ฝ์ด ์ฐ๋ ๋ ํ์ ์ฐ๋ ๋๊ฐ ์ฌ์ฉ๋์ง ์์ ๊ฒฝ์ฐ ํด๋น ์ฐ๋ ๋๋ terminate ๋๋ค. |
60์ด |
setMaxPoolSize |
์ฐ๋ ๋ ํ์ ์ต๋ ์ฌ์ด์ฆ |
Integer.MAX |
setQueueCapacity |
์ฐ๋ ๋ ํ ํ์ ์ฌ์ด์ฆ. corePoolSize ๊ฐ์๋ฅผ ๋์ด์๋ task๊ฐ ๋ค์ด์์ ๋ queue์ ํด๋น task๋ค์ด ์์ด๊ฒ ๋๋ค. ์ต๋๋ก maxPoolSize ๊ฐ์ ๋งํผ ์์ผ ์ ์๋ค. |
Integer.MAX |
์ฌ๊ธฐ์ corePoolSize, maxPoolSize, queueCapacity ์ด ์ธ ๊ฐ์ง ์ค์ ๊ฐ์ด ๊ฐ์ฅ ์ค์ํฉ๋๋ค.
์ฐ์ ์์์ ๋ดค๋ ์ฒซ ๋ฒ์งธ ์์ ์์๋ ์ด ์ธ ๊ฐ์ง ๊ฐ์ ๋ํด์ ๋ณ๋๋ก ์ค์ ์ ํ์ง ์์์์ต๋๋ค. ๊ทธ๋์ ์ฑ๊ธ ์ฐ๋ ๋๋ก ์์ ์ด ์ด๋ฃจ์ด์ก์ฃ .
corePoolSize
์ด๋ฒ์๋ corePoolSize๋ฅผ ์ฌ๋ ค๋ณด๊ฒ ์ต๋๋ค.
public static void main(String[] args) {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(5);
executor.initialize();
log.info("executing threads....");
Runnable r = () -> {
try {
log.info(Thread.currentThread().getName() + ", Now sleeping 10 seconds...");
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
};
for (int i = 0; i < 10; i++) {
executor.execute(r);
}
}
corePoolSize๋ฅผ 5๋ก ์ค์ ํ ์คํํด๋ณด์์ต๋๋ค. (queueCapacity์ maxPoolSize๊ฐ์ ํ์ฌ ๊ธฐ๋ณธ๊ฐ์ธ Integer.MAX ์ ๋๋ค)
08:52:50.423 [main] INFO com.keichee.test.service.TestService - executing threads....
08:52:50.456 [ThreadPoolTaskExecutor-3] INFO com.keichee.test.service.TestService - ThreadPoolTaskExecutor-3, Now sleeping 10 seconds...
08:52:50.456 [ThreadPoolTaskExecutor-2] INFO com.keichee.test.service.TestService - ThreadPoolTaskExecutor-2, Now sleeping 10 seconds...
08:52:50.456 [ThreadPoolTaskExecutor-5] INFO com.keichee.test.service.TestService - ThreadPoolTaskExecutor-5, Now sleeping 10 seconds...
08:52:50.456 [ThreadPoolTaskExecutor-1] INFO com.keichee.test.service.TestService - ThreadPoolTaskExecutor-1, Now sleeping 10 seconds...
08:52:50.456 [ThreadPoolTaskExecutor-4] INFO com.keichee.test.service.TestService - ThreadPoolTaskExecutor-4, Now sleeping 10 seconds...
08:53:00.460 [ThreadPoolTaskExecutor-1] INFO com.keichee.test.service.TestService - ThreadPoolTaskExecutor-1, Now sleeping 10 seconds...
08:53:00.460 [ThreadPoolTaskExecutor-2] INFO com.keichee.test.service.TestService - ThreadPoolTaskExecutor-2, Now sleeping 10 seconds...
08:53:00.461 [ThreadPoolTaskExecutor-3] INFO com.keichee.test.service.TestService - ThreadPoolTaskExecutor-3, Now sleeping 10 seconds...
08:53:00.461 [ThreadPoolTaskExecutor-4] INFO com.keichee.test.service.TestService - ThreadPoolTaskExecutor-4, Now sleeping 10 seconds...
08:53:00.461 [ThreadPoolTaskExecutor-5] INFO com.keichee.test.service.TestService - ThreadPoolTaskExecutor-5, Now sleeping 10 seconds...
์คํ๋์๋ง์ 5๊ฐ์ ์ฐ๋ ๋๊ฐ ์คํ๋๊ณ 10์ด ํ์ ๋ ๋ค๋ฅธ 5๊ฐ์ ์ฐ๋ ๋๊ฐ ์คํ๋ ๊ฒ์ ํ์ธํ ์ ์์ต๋๋ค. ์ฆ, queueCapacity์ maxPoolSize๊ฐ์ ๊ธฐ๋ณธ๊ฐ์ผ๋ก ํด๋์ผ๋ฉด corePoolSize์ ๊ฐ๋งํผ ์ฐ๋ ๋๊ฐ ๋์์ ์คํ๋๋ ๊ฒ์ ์ ์ ์์ต๋๋ค.
corePoolSize์ queueCapacity
๊ทธ๋ผ ์ด๋ฒ์๋ corePoolSize๋ default ๊ฐ์ธ 1๋ก ๋๋๊ณ queueCapacity์ maxPoolSize ๊ฐ์ 5๋ก ์ค์ ํด๋ณด๊ฒ ์ต๋๋ค. ๊ทธ๋ฆฌ๊ณ 10๊ฐ์ task๊ฐ ์คํ๋ ๋ poolSize, activeSize, queueSize ๊ฐ ์ด๋ป๊ฒ ๋ณํ๋์ง ํ์ธํ ์ ์๊ฒ ์ถ๋ ฅํด๋ณด๊ฒ ์ต๋๋ค. ๋, ์ถ๋ ฅ์ ์ข ์งง๊ฒ ํ๊ธฐ์ํด์ ์ฐ๋ ๋๋ช prefix๋ฅผ "my-"๋ก ๋ณ๊ฒฝํ์ต๋๋ค.
public static void main(String[] args) {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setThreadNamePrefix("my-");
executor.setQueueCapacity(5);
executor.setMaxPoolSize(5);
executor.initialize();
log.info("executing threads....");
Runnable r = () -> {
try {
log.info(Thread.currentThread().getName() + ", Now sleeping 10 seconds...");
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
};
for (int i = 0; i < 10; i++) {
executor.execute(r);
System.out.print("poolSize:" + executor.getPoolSize());
System.out.print(", active:" + executor.getActiveCount());
System.out.println(", queue:" + executor.getThreadPoolExecutor().getQueue().size());
}
}
์ด๋ค ๊ฒฐ๊ณผ๊ฐ ๋์ฌ ๊ฒ ๊ฐ์์ง ํ๋ฒ ์๊ฐ์ ํด๋ณด๊ณ ์๋ ๊ฒฐ๊ณผ๋ฅผ ํ์ธํด๋ณด์๊ธฐ ๋ฐ๋๋๋ค.
09:02:22.864 [main] INFO com.keichee.test.service.TestService - executing threads....
poolSize:1, active:1, queue:0
poolSize:1, active:1, queue:1
poolSize:1, active:1, queue:2
poolSize:1, active:1, queue:3
poolSize:1, active:1, queue:4
poolSize:1, active:1, queue:5
poolSize:2, active:2, queue:5
09:02:22.886 [my-1] INFO com.keichee.test.service.TestService - my-1, Now sleeping 10 seconds...
09:02:22.887 [my-2] INFO com.keichee.test.service.TestService - my-2, Now sleeping 10 seconds...
poolSize:3, active:3, queue:5
09:02:22.887 [my-3] INFO com.keichee.test.service.TestService - my-3, Now sleeping 10 seconds...
poolSize:4, active:4, queue:5
09:02:22.887 [my-4] INFO com.keichee.test.service.TestService - my-4, Now sleeping 10 seconds...
poolSize:5, active:5, queue:5
09:02:22.887 [my-5] INFO com.keichee.test.service.TestService - my-5, Now sleeping 10 seconds...
09:02:32.888 [my-1] INFO com.keichee.test.service.TestService - my-1, Now sleeping 10 seconds...
09:02:32.890 [my-2] INFO com.keichee.test.service.TestService - my-2, Now sleeping 10 seconds...
09:02:32.890 [my-4] INFO com.keichee.test.service.TestService - my-4, Now sleeping 10 seconds...
09:02:32.890 [my-5] INFO com.keichee.test.service.TestService - my-5, Now sleeping 10 seconds...
09:02:32.890 [my-3] INFO com.keichee.test.service.TestService - my-3, Now sleeping 10 seconds...
์ ์ถ๋ ฅ ๊ฒฐ๊ณผ๋ฅผ ๋ณด๋ฉด 10๊ฐ์ task๋ฅผ ์คํํ ๋ queue ์ฌ์ด์ฆ๊ฐ 0์์ 5๊น์ง ์ฌ๋ผ๊ฐ๊ณ ๊ทธ ์ดํ์ poolSize์ active ์ฌ์ด์ฆ๊ฐ ์ฆ๊ฐํ๋ ๊ฒ์ ์ ์ ์์ต๋๋ค. corePoolSize๊ฐ 1 ์ด๋ผ์ 2๋ฒ์งธ task๋ถํฐ 6๋ฒ์งธ task๊น์ง๋ queue์ ๋ค์ด๊ฐ๊ฒ ๋ฉ๋๋ค. ๊ทธ๋ฆฌ๊ณ 7๋ฒ์งธ task๋ถํฐ 10๋ฒ์งธ task๊น์ง 4๊ฐ์ task๋ maxPoolSize ๋ฅผ ๋์ด์์ง ์๋ ํ ์ถ๊ฐ๋ก ์ฐ๋ ๋๋ฅผ ์์ฑํ์ฌ pool์ ๋ฃ๊ณ ํด๋น ์ฐ๋ ๋๋ก ๊ฐ task๋ฅผ ์คํํ๊ฒ ๋ฉ๋๋ค.
๊ทธ๋ผ ๋ง์ฝ maxPoolSize๋ฅผ ๋์ด์ค ๋งํผ ๋ง์ ์์ task๋ค์ด ๋ค์ด์จ๋ค๋ฉด ์ด๋ป๊ฒ ๋ ๊น์?
Exception in thread "main" org.springframework.core.task.TaskRejectedException: Executor [java.util.concurrent.ThreadPoolExecutor@32eff876[Running, pool size = 5, active threads = 5, queued tasks = 5, completed tasks = 0]] did not accept task: com.keichee.test.service.TestService$$Lambda$22/0x00000008000ce840@5e0826e7
at org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor.execute(ThreadPoolTaskExecutor.java:324)
TaskRejectedException ์ค๋ฅ๊ฐ ๋ฐ์ํ๊ฒ ๋ฉ๋๋ค.
๋ฐ๋ผ์ ์ผ๋ง๋ ๋ง์ ์์ task๋ฅผ ์ํํด์ผ ํ๋์ง๋ฅผ ์ ํํ ์๊ณ corePoolSize, queueCapacity, maxPoolSize์ ์ ์ ํ ๊ฐ์ ์ธํ ํ์ฌ ์ฌ์ฉํด์ผ ํฉ๋๋ค. ๊ธฐ๋ณธ ๊ฐ์ผ๋ก ์ฌ์ฉํ๋ฉด TaskRejectedException์ ๋ณผ ์ผ์ ๊ฑฐ์ ์๊ฒ ์ง๋ง ๊ทธ ๋์ queue์ ์ด๋ง์ด๋งํ ์์ task๊ฐ ์์ด๊ฒ ์ฃ . ๊ทธ๋ฌ๋ค๊ฐ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ฐฐํฌ๋ ์ด๋ค ์ด์ ์ ์ํด์ ์ฌ๊ธฐ๋์ด ํ์ํ๊ฒ ๋๋ฉด ํด๋น queue์ ์์ฌ์๋ task๋ค์ ์ฌ๋ผ์ง๊ฒ ๋ฉ๋๋ค.
์คํ๋ง๋ถํธ์์ ์ฌ์ฉํ์ค ๋ถ๋ค์ ์๋ ํฌ์คํ ์ ์ฐธ๊ณ ํ์๋ฉด ์ข์ต๋๋ค.
์คํ๋ง ๋ถํธ์์ ThreadPoolTaskExecutor๋ฅผ ์ค์ ๋ฐ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ
'๐ป Programming > Java' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Java] ์๋ฐ ๋ฉํฐ์ฐ๋ ๋ (Multi Thread) (0) | 2020.04.17 |
---|---|
[Java] ์๋ฐ ๋ฉํฐ์ฐ๋ ๋์์ ๋ก๊ทธํ์ธ์ ์ํ uuid ์ค์ ํ๊ธฐ (0) | 2020.03.13 |
[Java] Convert timestamp(long) to date time string format and vice versa (0) | 2020.01.10 |
[Java] ์๋ฐ 8์ง์๋ฅผ 10์ง์๋ก ๋ณํํ๊ธฐ (0) | 2019.06.27 |
[Java] ์๋ฐ 1์ฐจ์ ๋ฐฐ์ด ์์ฑ(์ ์ธ ๋ฐ ์ด๊ธฐํ) (0) | 2019.06.25 |