๐ Java์์ ๋น๋๊ธฐ ์์ ์ฒ๋ฆฌ
Java์์ ๋น๋๊ธฐ ์์ ์ ์ฒ๋ฆฌํ๋ ๋ฐฉ๋ฒ์ ๋ค์ํ์ง๋ง, ExecutorService์ CompletableFuture๊ฐ ๊ฐ์ฅ ์ผ๋ฐ์ ์ด๊ณ ๋๋ฆฌ ์ฌ์ฉ๋๋ค.๐
โ 1. Thread ์ง์ ์ฌ์ฉ
Thread ํด๋์ค๋ฅผ ์ง์ ์์ฑํ์ฌ ์์ ์ ์คํํ๋ ๋ฐฉ๋ฒ.
๐ ์์
Thread thread = new Thread(() -> {
System.out.println("๋น๋๊ธฐ ์์
์คํ");
});
thread.start();
โ ์ฅ์
- ๊ฐ๋จํ ์์ ์ ์ ํฉ.
โ ๋จ์
- ์ค๋ ๋ ํ ๊ด๋ฆฌ๊ฐ ๋ถ๊ฐ๋ฅํ๊ณ , ์ง์ ๊ด๋ฆฌํด์ผ ํด์ ๋ณต์กํด์ง.
- ์ฑ๋ฅ ๋ฐ ์์ ๊ด๋ฆฌ ์ธก๋ฉด์์ ๋นํจ์จ์ .
โ 2. ExecutorService
์ค๋ ๋ ํ์ ๊ด๋ฆฌํ๋ฉฐ ํจ์จ์ ์ผ๋ก ๋น๋๊ธฐ ์์ ์ ์ฒ๋ฆฌ.
Runnable ๋๋ Callable์ ํ์ฉํ๋ ๊ฒ ๊ฐ์ฅ ์ผ๋ฐ์ .
1๏ธโฃ ExecutorService๋ ์ง์ ์ค๋ ๋ ํ์ ์์ฑํ์ฌ ์์ ์ ์คํ.
2๏ธโฃ submit() ๋ฉ์๋๋ ์์ ์ ์ค๋ ๋ ํ์ ํ์ ์ถ๊ฐํ์ฌ ๋น๋๊ธฐ์ ์ผ๋ก ์คํ.
3๏ธโฃ ์์ ์๋ฃ ํ shutdown()์ ํธ์ถํ์ฌ ์ค๋ ๋ ํ์ ์ข ๋ฃ.
๐ ์์
//์ค๋ ๋ ํ ํฌ๊ธฐ ์ค์ (๋์์ ์คํ ๊ฐ๋ฅํ ์์
์ ์ ํ)
ExecutorService executor = Executors.newFixedThreadPool(5);
executor.submit(() -> {
System.out.println("๋น๋๊ธฐ ์์
์คํ");
});
executor.shutdown();
๐ Runnable๊ณผ ํจ๊ป ์ฌ์ฉ (๋ฐํ๊ฐ โ)
ExecutorService executor = Executors.newFixedThreadPool(2);
Runnable task = () -> {
System.out.println("Runnable: ๋น๋๊ธฐ ์์
์คํ ์ค...");
};
executor.submit(task);
executor.shutdown();
๐ Callableํจ๊ป ์ฌ์ฉ (๋ฐํ๊ฐ โญ)
import java.util.concurrent.*;
public class CallableExample {
public static void main(String[] args) throws ExecutionException, InterruptedException {
ExecutorService executor = Executors.newFixedThreadPool(2);
Callable<String> task = () -> {
return "Callable: ๋น๋๊ธฐ ์์
์๋ฃ!";
};
Future<String> future = executor.submit(task); // ์์
์คํ ํ Future ๊ฐ์ฒด ๋ฐํ
System.out.println(future.get()); // get() ํธ์ถํด์ ๊ฒฐ๊ณผ ๋ฐ๊ธฐ
executor.shutdown();
}
}
โ ์ฅ์
- ์ค๋ ๋ ํ์ ์ฌ์ฌ์ฉํ์ฌ ์ฑ๋ฅ๊ณผ ์์ ๊ด๋ฆฌ๊ฐ ํจ์จ์ .
- ๋ค์ํ ์คํ ์ ์ฑ ์ ๊ณต (FixedThreadPool, CachedThreadPool, SingleThreadExecutor ๋ฑ).
- ์ค๋ ๋ ํ ํฌ๊ธฐ ๋ฐ ๋์์ ์ธ๋ฐํ๊ฒ ์ ์ด ๊ฐ๋ฅ.
โ ๋จ์
- ์์ ์๋ฃ ํ์ ๊ฒฐ๊ณผ๋ฅผ ์์งํ๊ฑฐ๋ ์ฒด์ด๋ํ๋ ค๋ฉด ์๋์ผ๋ก ๊ตฌํํด์ผ ํจ (ํน์ CompletableFuture ์ฌ์ฉ).
- ์ฝ๋๊ฐ ๋ณต์กํด์ง ์ ์์.
โ 3. CompletableFuture
Java 8๋ถํฐ ๋์ ๋ ๋น๋๊ธฐ ์์ ์ ๊ฒฐ๊ณผ๋ฅผ ๋ค๋ฃจ๊ธฐ ์ํ API.
- CompletableFuture.runAsync()๋ ๊ธฐ๋ณธ์ ์ผ๋ก ForkJoinPool.commonPool์ ์ฌ์ฉํ์ฌ ๋น๋๊ธฐ ์์ ์ ์ฒ๋ฆฌ.
- ๋ฐํ ๊ฐ ์์ด ๋น๋๊ธฐ์ ์ผ๋ก ์คํ๋๋ ์์ ์ ์ ํฉํฉ๋๋ค.
- ForkJoinPool ๋์ ์ปค์คํ
์ค๋ ๋ ํ์ ์ง์ ํ๋ ค๋ฉด ์ถ๊ฐ ์ธ์๋ฅผ ์ ๊ณตํฉ๋๋ค.
CompletableFuture.runAsync(() -> { /* ์์ ๋ก์ง */ }, executorService); - ์ฒด์ด๋(thenApply, thenAccept, thenRun)์ ํ์ฉํ๋ฉด ์์ ์ ์ฝ๊ฒ ์ฐ๊ฒฐ
๐ runAsync ์ฌ์ฉ (๋ฐํ๊ฐ โ)
CompletableFuture.runAsync(() -> {
System.out.println("Runnable์ฒ๋ผ ์คํ๋จ!");
});
// ํจ์ ๋ฆฌํด๊ฐ ํ์
public CompletableFuture<Void> function(String param) throws Exception {
return CompletableFuture.runAsync(() -> {
// ์์
๋ก์ง
});
}
๐ supplyAsync ์ฌ์ฉ (๋ฐํ๊ฐ โญ)
CompletableFuture.supplyAsync(() -> {
return "๋น๋๊ธฐ ์์
๊ฒฐ๊ณผ";
}).thenAccept(result -> {
System.out.println("๊ฒฐ๊ณผ: " + result);
});
// or
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
return "Callable์ฒ๋ผ ์คํ๋จ!";
});
future.thenAccept(System.out::println); // ๊ฒฐ๊ณผ ์ถ๋ ฅ
๐ ์ปค์คํ ์ค๋ ๋ ํ + CompletableFuture
ExecutorService executor = Executors.newFixedThreadPool(2);
CompletableFuture.runAsync(() -> {
// ์์
๋ก์ง
}, executor);
executor.shutdown();
๐ ๋น๋๊ธฐ ์์ ์ฌ๋ฌ๊ฐ ์๋ฃ ๊ธฐ๋ค๋ฆฌ๊ธฐ
List<CompletableFuture<Void>> futures = new ArrayList<>();
for (int i = 0; i < 5; i++) {
CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
try {
Thread.sleep(1000); // 1์ด ๋์ ๋๊ธฐ
System.out.println(Thread.currentThread().getName() + " ์์
์๋ฃ!");
} catch (InterruptedException e) {
e.printStackTrace();
}
});
futures.add(future);
}
// ๋ชจ๋ ์์
์ด ๋๋ ๋๊น์ง ๋๊ธฐ
CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();
System.out.println("โ
๋ชจ๋ ๋น๋๊ธฐ ์์
์๋ฃ ํ ์คํ!");
โ ์ฅ์
- ๋น๋๊ธฐ ์์ ์ฒด์ด๋ ๋ฐ ๊ฒฐ๊ณผ/์๋ฌ ์ฒ๋ฆฌ ๊ฐํธ.
- ForkJoinPool๊ณผ ์ ํตํฉ๋๋ค.
- ๊ธฐ๋ณธ์ ์ผ๋ก ์ค๋ ๋ ํ์ ๊ด๋ฆฌ๊ฐ ํ์ ์์.
โ ๋จ์
- ๊ฐ๋จํ ์์ ์ ์ฌ์ฉํ๋ฉด ์คํ๋ ค ๋ณต์กํด์ง ์ ์์.
- ๊ธฐ๋ณธ ForkJoinPool์ ํฌ๊ธฐ๊ฐ ์ ํ์ ์ด๋ฏ๋ก ๋๋์ ์์ ์ด ๋ฐ์ํ๋ฉด ์ปค์คํ ์ค๋ ๋ ํ ํ์.
๐ฅ ExecutorService VS CompletableFuture
ํน์ง | ExecutorService | CompletableFuture |
์ฌ์ฉ ๋ชฉ์ | ์ค๋ ๋ ํ ์ง์ ๊ด๋ฆฌ & ์์ ์คํ | ๋น๋๊ธฐ ์์ ์ฒด์ด๋ & ๊ฒฐ๊ณผ ์ฒ๋ฆฌ |
์ค๋ ๋ ๊ด๋ฆฌ | ์ง์ ์ค๋ ๋ ํ ํฌ๊ธฐ ์ค์ ๋ฐ ๊ด๋ฆฌ ํ์ | ๊ธฐ๋ณธ์ ์ผ๋ก ForkJoinPool.commonPool ์ฌ์ฉ (ํ์์ ์ปค์คํ ๊ฐ๋ฅ) |
์์ ์ฐ๊ฒฐ (์ฒด์ด๋) | ์ง์ ์ถ๊ฐ ๊ตฌํ ํ์ (Future ์ฌ์ฉ ์ ์ ํ์ ) | thenApply, thenAccept, handle ๋ฑ์ ํตํด ์ฝ๊ฒ ์ฐ๊ฒฐ |
์์ธ ์ฒ๋ฆฌ | try-catch๋ก ์ง์ ์ฒ๋ฆฌ | exceptionally, handle ์ง์ |
์ง์ ์ข ๋ฃ ํ์ | shutdown() ํธ์ถ ํ์ | ๊ธฐ๋ณธ ํ(commonPool)์ JVM ์ข ๋ฃ ์ ์๋ ์ข ๋ฃ |
์ถ๊ฐ ์์ ์ง์ | ์ ํ์ (submit ๋ฐ Future.get์ผ๋ก ๊ฒฐ๊ณผ ํ์ธ) | ์ฐ์ ์์ , ๊ฒฐ๊ณผ ์ฒ๋ฆฌ, ์์ธ ์ฒ๋ฆฌ ๋ฑ ๋ค์ํ ๊ธฐ๋ฅ ์ง์ |
์ฝ๋ ๊ฐ๊ฒฐ์ฑ | ๋น๊ต์ ์ฅํฉํ ์ ์์ | ๊ฐ๊ฒฐํ๊ณ ์ฝ๊ธฐ ์ฌ์ |
๐ ๊ฒฐ๋ก
- ์์ ๊ฐ ์ฐ๊ฒฐ & ๊ฐ๋จํ ๋น๋๊ธฐ ์์ → CompletableFuture ์ฌ์ฉ ์ถ์ฒ!
- ์ค๋ ๋ ํ์ ์ธ๋ฐํ๊ฒ ์ ์ดํด์ผ ํ ๋ → ExecutorService ์ฌ์ฉ ์ถ์ฒ!
'Backend > JAVA' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
JNDI๋? (0) | 2025.02.26 |
---|---|
์๋ฐ(Spring) ๊ธฐ๋ณธ ์์ธ ์ฒ๋ฆฌ (0) | 2025.02.23 |
HttpURLConnection (0) | 2024.06.07 |
๋ธ๋กํนํ(Blocking Queue) (0) | 2024.06.05 |
Callable, Runnable, Future (0) | 2024.06.05 |