Executor ์ธํฐํ์ด์ค๊ฐ ํ์ํ ์ด์ ๋ ๋ฌด์์ ๋๊น?
Java 5 ์ด์ ์๋ ์ ํ๋ฆฌ์ผ์ด์ ์์ ๋ชจ๋ ์์ฒด ์ฝ๋ ์ค๋ ๋ ๊ด๋ฆฌ๋ฅผ ์์ฑํด์ผ ํ์ต๋๋ค. ๋ํ,์ ์ค๋ ๋๊ฐ์ฒด๋ ๋ฆฌ์์ค๋ฅผ ๋ง์ด ์ฌ์ฉํ๋ ์์ ์ด๋ฉฐ ๋ชจ๋ ๊ฒฝ๋ ์์ ์ ๋ํด ์ ์ค๋ ๋๋ฅผ ๋ง๋๋ ๊ฒ์ ์ด์น์ ๋ง์ง ์์ต๋๋ค. ๊ทธ๋ฆฌ๊ณ ์ด ๋ฌธ์ ๋ ๋ฉํฐ์ค๋ ๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ชจ๋ ๊ฐ๋ฐ์์๊ฒ ์น์ํ๊ธฐ ๋๋ฌธ์ ์ด ๊ธฐ๋ฅ์ Executor ํ๋ ์์ํฌ๋ก Java์ ๋์ ํ๊ธฐ๋ก ๊ฒฐ์ ํ์ต๋๋ค.
ํฐ ์์ด๋์ด๋ ๋ฌด์์ ๋๊น? ๊ฐ๋จํฉ๋๋ค. ์ ์์ ๋ง๋ค ์ ์ค๋ ๋๋ฅผ ๋ง๋๋ ๋์ ์ค๋ ๋๋ฅผ ์ผ์ข ์ "์ ์ฅ์"์ ๋ณด๊ดํ๊ณ ์ ์์ ์ด ๋์ฐฉํ๋ฉด ์ ์์ ์ ๋ง๋๋ ๋์ ๊ธฐ์กด ์ค๋ ๋๋ฅผ ๊ฒ์ํฉ๋๋ค.
์ด ํ๋ ์์ํฌ์ ์ฃผ์ ์ธํฐํ์ด์ค๋ Executor , ExecutorService ๋ฐ ScheduledExecutorService ์ด๋ฉฐ ๊ฐ๊ฐ ์ด์ ์ธํฐํ์ด์ค์ ๊ธฐ๋ฅ์ ํ์ฅํฉ๋๋ค.
Executor ์ธํฐํ์ด์ค๋ ๊ธฐ๋ณธ ์ธํฐํ์ด์ค์ ๋๋ค. Runnable ๊ฐ์ฒด ์ ์ํด ๊ตฌํ๋๋ ๋จ์ผ ๋ฌดํจ ์คํ(Runnable ๋ช ๋ น) ๋ฉ์๋๋ฅผ ์ ์ธํฉ๋๋ค .
ExecutorService ์ธํฐํ์ด์ค ๊ฐ ๋ ํฅ๋ฏธ๋กญ์ต๋๋ค. ์์ ์๋ฃ๋ฅผ ๊ด๋ฆฌํ๋ ๋ฐฉ๋ฒ๊ณผ ์ผ์ข ์ ๊ฒฐ๊ณผ๋ฅผ ๋ฐํํ๋ ๋ฐฉ๋ฒ์ด ์์ต๋๋ค. ๋ฐฉ๋ฒ์ ์์ธํ ์ดํด ๋ณด๊ฒ ์ต๋๋ค.
๋ฐฉ๋ฒ | ์ค๋ช |
---|---|
๋ฌดํจ ์ข ๋ฃ(); | ์ด ๋ฉ์๋๋ฅผ ํธ์ถํ๋ฉด ExecutorService ๊ฐ ์ค์ง๋ฉ๋๋ค . ์ฒ๋ฆฌ๋ฅผ ์ํด ์ด๋ฏธ ์ ์ถ๋ ๋ชจ๋ ์์ ์ ์๋ฃ๋์ง๋ง ์ ์์ ์ ์๋ฝ๋์ง ์์ต๋๋ค. |
List<Runnable> shutdownNow(); |
์ด ๋ฉ์๋๋ฅผ ํธ์ถํ๋ฉด ExecutorService ๊ฐ ์ค์ง๋ฉ๋๋ค . ์ฒ๋ฆฌ๋ฅผ ์ํด ์ด๋ฏธ ์ ์ถ๋ ๋ชจ๋ ์์ ์ ๋ํด Thread.interrupt ๊ฐ ํธ์ถ๋ฉ๋๋ค. ์ด ๋ฉ์๋๋ ๋๊ธฐ ์ค์ธ ์์ ๋ชฉ๋ก์ ๋ฐํํฉ๋๋ค. ๋ฉ์๋๋ ๋ฉ์๋๊ฐ ํธ์ถ๋ ๋ "์งํ ์ค"์ธ ๋ชจ๋ ์์ ์ด ์๋ฃ๋ ๋๊น์ง ๊ธฐ๋ค๋ฆฌ์ง ์์ต๋๋ค. ๊ฒฝ๊ณ : ์ด ๋ฉ์๋๋ฅผ ํธ์ถํ๋ฉด ๋ฆฌ์์ค๊ฐ ๋์ถ๋ ์ ์์ต๋๋ค. |
๋ถ์ธ isShutdown(); | ExecutorService ๊ฐ ์ค์ง๋์๋์ง ํ์ธํฉ๋๋ค . |
๋ถ์ธ isTerminated(); | ExecutorService ์ข ๋ฃ ํ ๋ชจ๋ ์์ ์ด ์๋ฃ๋๋ฉด true๋ฅผ ๋ฐํํฉ๋๋ค . shutdown() ๋๋ shutdownNow()๊ฐ ํธ์ถ๋ ๋๊น์ง ํญ์ false๋ฅผ ๋ฐํํฉ๋๋ค . |
๋ถ์ธ awaitTermination(long timeout, TimeUnit unit)์ InterruptedException์ ๋ฐ์์ํต๋๋ค. |
shutdown() ๋ฉ์๋๊ฐ ํธ์ถ ๋ ํ ์ด ๋ฉ์๋๋ ๋ค์ ์กฐ๊ฑด ์ค ํ๋๊ฐ ์ฐธ์ผ ๋๊น์ง ํธ์ถ๋ ์ค๋ ๋๋ฅผ ์ฐจ๋จํฉ๋๋ค.
๋ชจ๋ ์์ ์ด ์๋ฃ๋๋ฉด true๋ฅผ ๋ฐํ ํ๊ณ ์ข ๋ฃ ์ ์ ์ ํ ์๊ฐ์ด ๊ฒฝ๊ณผํ๋ฉด false๋ฅผ ๋ฐํํฉ๋๋ค. |
<T> Future<T> ์ ์ถ(Callable<T> ์์ ); |
Callable ์์ ์ ExecutorService ์ ์ถ๊ฐ ํ๊ณ Future ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ๋ ๊ฐ์ฒด๋ฅผ ๋ฐํํฉ๋๋ค . <T> ๋ ์ ๋ฌ๋ ์์ ์ ๊ฒฐ๊ณผ ์ ํ์ ๋๋ค. |
<T> Future<T> ์ ์ถ(์คํ ๊ฐ๋ฅํ ์์ , T ๊ฒฐ๊ณผ); |
Runnable ์์ ์ ExecutorService ์ ์ถ๊ฐ ํ๊ณ Future ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ๋ ๊ฐ์ฒด๋ฅผ ๋ฐํํฉ๋๋ค . T ๊ฒฐ๊ณผ ๋งค๊ฐ๋ณ์๋ ๊ฒฐ๊ณผ์ ๋ํ get() ๋ฉ์๋ ํธ์ถ์ ์ํด ๋ฐํ๋๋ ๊ฒ์ ๋๋ค.๋ฏธ๋ ๊ฐ์ฒด. |
Future<?> ์ ์ถ(์คํ ๊ฐ๋ฅํ ์์ ); |
Runnable ์์ ์ ExecutorService ์ ์ถ๊ฐ ํ๊ณ Future ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ๋ ๊ฐ์ฒด๋ฅผ ๋ฐํํฉ๋๋ค . ๊ฒฐ๊ณผ Future ๊ฐ์ฒด์์ get() ๋ฉ์๋๋ฅผ ํธ์ถํ๋ฉด null์ ์ป์ต๋๋ค. |
<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> ์์ ) throws InterruptedException; |
Callable ์์ ๋ชฉ๋ก์ ExecutorService ์ ์ ๋ฌํฉ๋๋ค . ์์ ๊ฒฐ๊ณผ๋ฅผ ์ป์ ์ ์๋ Future ๋ชฉ๋ก์ ๋ฐํํฉ๋๋ค. ์ ์ถ๋ ๋ชจ๋ ์์ ์ด ์๋ฃ๋๋ฉด ์ด ๋ชฉ๋ก์ด ๋ฐํ๋ฉ๋๋ค. ๋ฉ์๋๊ฐ ์คํ๋๋ ๋์ ์์ ์ปฌ๋ ์ ์ด ์์ ๋๋ฉด ์ด ๋ฉ์๋์ ๊ฒฐ๊ณผ๋ ์ ์๋์ง ์์ต๋๋ค . |
<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit) throws InterruptedException; |
Callable ์์ ๋ชฉ๋ก์ ExecutorService ์ ์ ๋ฌํฉ๋๋ค . ์์ ๊ฒฐ๊ณผ๋ฅผ ์ป์ ์ ์๋ Future ๋ชฉ๋ก์ ๋ฐํํฉ๋๋ค. ์ด ๋ชฉ๋ก์ ์ ๋ฌ๋ ๋ชจ๋ ์์ ์ด ์๋ฃ๋๊ฑฐ๋ ๋ฉ์๋์ ์ ๋ฌ๋ ์ ํ ์๊ฐ์ด ๊ฒฝ๊ณผํ ํ ์ค ๋จผ์ ๋๋ํ๋ ์์ ์ ๋ฐํ๋ฉ๋๋ค. ์ ํ ์๊ฐ์ด ๊ฒฝ๊ณผํ๋ฉด ์๋ฃ๋์ง ์์ ์์ ์ด ์ทจ์๋ฉ๋๋ค. ์ฐธ๊ณ : ์ทจ์๋ ์์ ์ด ์คํ์ ์ค์งํ์ง ์์ ์ ์์ต๋๋ค(์์ ์์ ์ด ๋ถ์์ฉ์ ๋ณผ ์ ์์). ๋ฉ์๋๊ฐ ์คํ๋๋ ๋์ ์์ ์ปฌ๋ ์ ์ด ์์ ๋๋ฉด ์ด ๋ฉ์๋์ ๊ฒฐ๊ณผ๋ ์ ์๋์ง ์์ต๋๋ค . |
<T> T invokeAny(Collection<? extends Callable<T>> tasks)๋ InterruptedException, ExecutionException์ ๋ฐ์์ํต๋๋ค. |
Callable ์์ ๋ชฉ๋ก์ ExecutorService ์ ์ ๋ฌํฉ๋๋ค . ์์ธ(์๋ ๊ฒฝ์ฐ)๋ฅผ throwํ์ง ์๊ณ ์๋ฃ๋ ์์ (์๋ ๊ฒฝ์ฐ) ์ค ํ๋์ ๊ฒฐ๊ณผ๋ฅผ ๋ฐํํฉ๋๋ค. ๋ฉ์๋๊ฐ ์คํ๋๋ ๋์ ์์ ์ปฌ๋ ์ ์ด ์์ ๋๋ฉด ์ด ๋ฉ์๋์ ๊ฒฐ๊ณผ๋ ์ ์๋์ง ์์ต๋๋ค . |
<T> T invokeAny(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException; |
Callable ์์ ๋ชฉ๋ก์ ExecutorService ์ ์ ๋ฌํฉ๋๋ค . ๋ฉ์๋์ ์ ๋ฌ๋ ์ ํ ์๊ฐ์ด ๊ฒฝ๊ณผํ๊ธฐ ์ ์ ์์ธ๋ฅผ throwํ์ง ์๊ณ ์๋ฃ๋ ์์ (์๋ ๊ฒฝ์ฐ) ์ค ํ๋์ ๊ฒฐ๊ณผ๋ฅผ ๋ฐํํฉ๋๋ค. ๋ฉ์๋๊ฐ ์คํ๋๋ ๋์ ์์ ์ปฌ๋ ์ ์ด ์์ ๋๋ฉด ์ด ๋ฉ์๋์ ๊ฒฐ๊ณผ๋ ์ ์๋์ง ์์ต๋๋ค . |
ExecutorService ์์ ์ ๋ํ ๊ฐ๋จํ ์๋ฅผ ์ดํด๋ณด๊ฒ ์ต๋๋ค .
import java.util.List;
import java.util.concurrent.*;
public class ExecutorServiceTest {
public static void main(String[] args) throws InterruptedException, ExecutionException, TimeoutException {
//Create an ExecutorService for 2 threads
java.util.concurrent.ExecutorService executorService = new ThreadPoolExecutor(2, 2, 60, TimeUnit.SECONDS, new ArrayBlockingQueue<>(10));
// Create 5 tasks
MyRunnable task1 = new MyRunnable();
MyRunnable task2 = new MyRunnable();
MyRunnable task3 = new MyRunnable();
MyRunnable task4 = new MyRunnable();
MyRunnable task5 = new MyRunnable();
final List<MyRunnable> tasks = List.of(task1, task2, task3, task4, task5);
// Pass a list that contains the 5 tasks we created
final List<Future<Void>> futures = executorService.invokeAll(tasks, 6, TimeUnit.SECONDS);
System.out.println("Futures received");
// Stop the ExecutorService
executorService.shutdown();
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(executorService.isShutdown());
System.out.println(executorService.isTerminated());
}
public static class MyRunnable implements Callable<Void> {
@Override
public void call() {
// Add 2 delays. When the ExecutorService is stopped, we will see which delay is in progress when the attempt is made to stop execution of the task
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
System.out.println("sleep 1: " + e.getMessage());
}
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
System.out.println("sleep 2: " + e.getMessage());
}
System.out.println("done");
return null;
}
}
}
์ฐ์ถ:
์๋ฃ
ํจ์ฒ๊ฐ ์์ ํ
์๋ฉด 1: ์๋ฉด ์ค๋จ
์๋ฉด 1: ์๋ฉด ์ค๋จ
์๋ฃ
์๋ฃ
์ฐธ
์ฐธ
๊ฐ ์์ ์ 5์ด ๋์ ์คํ๋ฉ๋๋ค. ์ฐ๋ฆฌ๋ ๋ ๊ฐ์ ์ค๋ ๋์ ๋ํ ํ์ ๋ง๋ค์์ผ๋ฏ๋ก ์ฒ์ ๋ ์ค์ ์ถ๋ ฅ์ด ์๋ฒฝํ๊ฒ ์ดํด๋ฉ๋๋ค.
ํ๋ก๊ทธ๋จ์ด ์์๋๊ณ 6์ด ํ์ invokeAll ๋ฉ์๋๊ฐ ์๊ฐ ์ด๊ณผ๋๊ณ ๊ฒฐ๊ณผ๊ฐ Futures ๋ชฉ๋ก์ผ๋ก ๋ฐํ๋ฉ๋๋ค . ์ด๊ฒ์ ์ถ๋ ฅ ๋ฌธ์์ด Futures received ์์ ๋ณผ ์ ์์ต๋๋ค .
์ฒ์ ๋ ๊ฐ์ง ์์ ์ด ์๋ฃ๋๋ฉด ๋ ๊ฐ์ง ์์ ์ด ๋ ์์๋ฉ๋๋ค. ํ์ง๋ง invokeAll ๋ฉ์๋์ ์ค์ ๋ ์ ํ ์๊ฐ์ด ๊ฒฝ๊ณผํ๊ธฐ ๋๋ฌธ์ ์ด ๋ ์์ ์ ์๋ฃํ ์๊ฐ์ด ์์ต๋๋ค. ๊ทธ๋ค์ "์ทจ์" ๋ช ๋ น์ ๋ฐ์ต๋๋ค. ์ด๊ฒ์ด ์ถ๋ ฅ์ sleep 1: sleep interrupted ๊ฐ ํฌํจ๋ ๋ ์ค์ด ์๋ ์ด์ ์ ๋๋ค .
๊ทธ๋ฐ ๋ค์ done ์ด ์๋ ๋ ์ค์ ๋ ๋ณผ ์ ์์ต๋๋ค . ์ด๊ฒ์ด invokeAll ๋ฉ์๋๋ฅผ ์ค๋ช ํ ๋ ์ธ๊ธํ ๋ถ์์ฉ์ ๋๋ค .
๋ค์ฏ ๋ฒ์งธ์ด์ ๋ง์ง๋ง ์์ ์ ์์์กฐ์ฐจ ๋์ง ์์ผ๋ฏ๋ก ์ถ๋ ฅ์ ์๋ฌด๊ฒ๋ ํ์๋์ง ์์ต๋๋ค.
๋ง์ง๋ง ๋ ์ค์ isShutdown ๋ฐ isTerminated ๋ฉ์๋๋ฅผ ํธ์ถํ ๊ฒฐ๊ณผ์ ๋๋ค .
๋๋ฒ๊ทธ ๋ชจ๋์์ ์ด ์์ ๋ฅผ ์คํํ๊ณ ์๊ฐ ์ ํ์ด ๊ฒฝ๊ณผํ ํ ์์ ์ํ๋ฅผ ์ดํด๋ณด๋ ๊ฒ๋ ํฅ๋ฏธ๋กญ์ต๋๋ค( executorService.shutdown(); ์ ์ฌ์ฉํ์ฌ ์ค์ ์ค๋จ์ ์ ์ค์ ).
๋ ๊ฐ์ ์์ ์ด ์ ์์ ์ผ๋ก ์๋ฃ๋๊ณ ์ธ ๊ฐ์ ์์ ์ด "์ทจ์๋จ" ์ธ ๊ฒ์ ๋ณผ ์ ์์ต๋๋ค .
ScheduledExecutorService
์คํ์์ ๋ํ ๋ ผ์๋ฅผ ๋ง์น๊ธฐ ์ํด ScheduledExecutorService ๋ฅผ ์ดํด๋ณด๊ฒ ์ต๋๋ค .
4๊ฐ์ง ๋ฐฉ๋ฒ์ด ์์ต๋๋ค.
๋ฐฉ๋ฒ | ์ค๋ช |
---|---|
public ScheduledFuture<?> schedule(์คํ ๊ฐ๋ฅํ ๋ช ๋ น, ๊ธด ์ง์ฐ, TimeUnit ๋จ์); | ์ ๋ฌ๋ Runnable ์์ ์ด ์ธ์๋ก ์ง์ ๋ ์ง์ฐ ํ ํ ๋ฒ ์คํ๋๋๋ก ์์ฝํฉ๋๋ค. |
public <V> ScheduledFuture<V> schedule(Callable<V> ํธ์ถ ๊ฐ๋ฅ, ๊ธด ์ง์ฐ, TimeUnit ๋จ์); | ์ ๋ฌ๋ Callable ํ์คํฌ๊ฐ ์ธ์๋ก ์ง์ ๋ ์ง์ฐ ํ ํ ๋ฒ ์คํ๋๋๋ก ์ค์ผ์คํฉ๋๋ค. |
public ScheduledFuture<?> scheduleAtFixedRate(์คํ ๊ฐ๋ฅํ ๋ช ๋ น, ๊ธด initialDelay, ๊ธด ๊ธฐ๊ฐ, TimeUnit ๋จ์); | ์ ๋ฌ๋ ์์ ์ ์ฃผ๊ธฐ์ ์คํ์ ์์ฝํฉ๋๋ค. ์ด ์์ ์ initialDelay ์ดํ ์ฒ์์ผ๋ก ์คํ๋๊ณ ๊ฐ ํ์ ์คํ์ period ์ดํ์ ์์๋ฉ๋๋ค . |
public ScheduledFuture<?> scheduleWithFixedDelay(์คํ ๊ฐ๋ฅํ ๋ช ๋ น, ๊ธด initialDelay, ๊ธด ์ง์ฐ, TimeUnit ๋จ์); | initialDelay ์ดํ ์ฒ์์ผ๋ก ์คํ๋ ์ ๋ฌ๋ ์์ ์ ์ฃผ๊ธฐ์ ์คํ์ ์์ฝ ํ๊ณ ๊ฐ ํ์ ์คํ์ ์ง์ฐ (์ด์ ์คํ ์๋ฃ์ ํ์ฌ ์คํ ์์ ์ฌ์ด์ ๊ธฐ๊ฐ) ํ์ ์์๋ฉ๋๋ค . |
GO TO FULL VERSION