4์ฃผ์ฐจ ์๋ฃ์ ๋ชจ๋ ํ ํฝ์ "๊ธฐ์ด โ ๋๊ธฐํ โ ํ๋ ฅ โ ์ถ์ํ" ์์๋ก ์ฌ๋ฐฐ์ดํ ํ์ต ๊ฒฝ๋ก.
1~3์ฃผ์ฐจ์์ ๋จ์ผ ์ค๋ ๋ ํ๋ฆ์ ๋ดค๋ค๋ฉด, 4์ฃผ์ฐจ๋ ์ฌ๋ฌ ์ค๋ ๋๊ฐ ๋์์ ์์ง์ด๋ ์ธ๊ณ ์ ๋ชจ๋ ๊ฒ์ ๋ค๋ฃฌ๋ค.
๋ฉด์ ยท์ค๋ฌด์์ ๊ฐ์ฅ ์์ฃผ ๋ฑ์ฅํ๋ ์์ญ์ด๋ฉฐ, ๋ถ๋๋ ๊ฐ์ฅ ๋ง๋ค.
[Phase 1] ๋์์ฑ์ ๊ธฐ์ด โ ํ๋ก์ธ์ค์ ์ค๋ ๋
โ
[Phase 2] Sync/Async ร Blocking/Non-Blocking 4๋ถ๋ฉด
โ
[Phase 3] ์ค๋ ๋ ๋ง๋ค๊ณ ๋ค๋ฃจ๊ธฐ
โ
[Phase 4] ๋๊ธฐํ โ synchronized์ ๋ฉ๋ชจ๋ฆฌ ๊ฐ์์ฑ โโโ 4์ฃผ์ฐจ 1์ฐจ ์ ์
โ
[Phase 5] ์ ๊ตํ ๋ฝ โ LockSupport์ ReentrantLock
โ
[Phase 6] ์ค๋ ๋ ๊ฐ ํ๋ ฅ โ ์์ฐ์/์๋น์, ์ธํฐ๋ฝํธ, yield
โ
[Phase 7] ์ง์ ์ฌ์ฉ์ ํ๊ณ์ Executor ํ๋ ์์ํฌ โโโ 4์ฃผ์ฐจ 2์ฐจ ์ ์
โ
[Phase 8] ๊ณ ๊ธ ๋น๋๊ธฐ โ CompletableFuture์ ForkJoinPool
์ด 8 Phase ร 35 Unit โ ์ค์ต ๋น์ค์ด ๋งค์ฐ ๋์ ์์ถ 7์ผ ๋๋ ์ฌ์ 14์ผ ๊ถ์ฅ.
| ์์ญ | 1์ฃผ์ฐจ | 2์ฃผ์ฐจ | 3์ฃผ์ฐจ | 4์ฃผ์ฐจ (์ง๊ธ) |
|---|---|---|---|---|
| ๋ฉ๋ชจ๋ฆฌ ๋ชจ๋ธ | Heap/Stack | Method Area 3๋ถํ | (์์) | ์ค๋ ๋๋ณ ์บ์ vs ๋ฉ์ธ ๋ฉ๋ชจ๋ฆฌ, volatile |
| ์ปฌ๋ ์ | ๊ฐ์ | ๋ด๋ถ ๊ตฌ์กฐ | ์ ์ฒด ์ง๋ | ConcurrentHashMap, ConcurrentLinkedQueue |
| I/O | ๊ฐ์ | (์์) | NIO/Stream/Channel | Blocking vs Non-Blocking ๊น์ด |
| ์ ๊ท | OOP | Reflection | ๋๋ค/์คํธ๋ฆผ | synchronized, Lock, Executor, CompletableFuture, ForkJoin |
| Day | Phase | ํ์ต ๋ชฉํ |
|---|---|---|
| 1์ผ์ฐจ | Phase 1 + 2 | ํ๋ก์ธ์ค/์ค๋ ๋ ๊ธฐ์ด + 4๋ถ๋ฉด ๋งคํธ๋ฆญ์ค |
| 2์ผ์ฐจ | Phase 3 | Thread/Runnable, ๋ฐ๋ชฌ, join() |
| 3์ผ์ฐจ | Phase 4 | synchronized + volatile (โ 1์ฐจ ์ ์ ) |
| 4์ผ์ฐจ | Phase 5 | LockSupport, ReentrantLock, tryLock |
| 5์ผ์ฐจ | Phase 6 | wait/notify, ์ธํฐ๋ฝํธ, yield |
| 6์ผ์ฐจ | Phase 7 | Executor ํ๋ ์์ํฌ ์ ์ฒด (โ 2์ฐจ ์ ์ ) |
| 7์ผ์ฐจ | Phase 8 | CompletableFuture, ForkJoinPool |
์ฌ์ ์ผ์ (14์ผ): Phase 4ยท7์ ๊ฐ 2์ผ์ฉ ๋ฐฐ์ . ๋์์ฑ์ ์ฝ๋๋ฅผ ์ง์ ๋๋ ค๋ด์ผ ์ฒดํ๋จ.
๋ชฉํ: ๋ฉํฐํ์คํนยท๋ฉํฐํ๋ก์ธ์ฑยทํ๋ก์ธ์คยท์ค๋ ๋์ ์ ์์ ๋ฉ๋ชจ๋ฆฌ ๊ตฌ์กฐ๋ฅผ ๋ช ํํ ์ก๋๋ค.
์ ์ ์ง์: 1์ฃผ์ฐจ Phase 4 (JVM)
ํต์ฌ ๊ฐ๋
| ๊ตฌ๋ถ | ๋ฉํฐํ์คํน | ๋ฉํฐํ๋ก์ธ์ฑ |
|---|---|---|
| ์ ์ | 1๊ฐ CPU(์ฝ์ด)๊ฐ ์ฌ๋ฌ ์์ ์ ๋ฒ๊ฐ์ ์คํ | ์ฌ๋ฌ CPU(์ฝ์ด)๊ฐ ๋์์ ์์ |
| ๊ธฐ๋ฐ | ์ํํธ์จ์ด (์๋ถํ ์ค์ผ์ค๋ง) | ํ๋์จ์ด (๋ค์ค ์ฝ์ด) |
| ์์ | OS์ ๋ฉํฐํ๋ก๊ทธ๋จ ํ๊ฒฝ | ํ๋ ๋ฉํฐ์ฝ์ด CPU |
์๊ธฐ ์ ๊ฒ
์ ์ ์ง์: Unit 1.1
ํต์ฌ ๊ฐ๋
ํ๋ก์ธ์ค:
์ค๋ ๋:
๋ฉ๋ชจ๋ฆฌ ๊ตฌ์ฑ:
ํ๋ก์ธ์ค ๋ฉ๋ชจ๋ฆฌ
โโโ ์ฝ๋ ์น์
โ
โโโ ๋ฐ์ดํฐ ์น์
โ ๋ชจ๋ ์ค๋ ๋๊ฐ ๊ณต์
โโโ ํ(Heap) โ
โโโ ์คํ(Stack) โ ์ค๋ ๋๋ง๋ค ๊ฐ๋ณ ํ ๋น
์๊ธฐ ์ ๊ฒ
์ ์ ์ง์: Unit 1.2, 2์ฃผ์ฐจ Phase 1
ํต์ฌ ๊ฐ๋
๋ฉํฐ์ค๋ ๋ ๊ด์ ์์์ ๋ณ์ ๋งคํ:
| ๋ณ์ | ์ ์ฅ ์์น | ๋ฉํฐ์ค๋ ๋ ๊ด์ |
|---|---|---|
| ์ง์ญ ๋ณ์ | Stack (์ค๋ ๋๋ณ) | ์ค๋ ๋ ์์ (๊ณต์ ์ ๋จ) |
| ์ธ์คํด์ค ๋ณ์ | Heap | ๊ณต์ โ ๋๊ธฐํ ํ์ |
| ํด๋์ค ๋ณ์ (static) | Method Area (Data) | ๊ณต์ โ ๋๊ธฐํ ํ์ |
| ์ ์ญ ๋ณ์ (static) | Method Area (Data) | ๊ณต์ โ ๋๊ธฐํ ํ์ |
ํต์ฌ ํต์ฐฐ: "์ค๋ ๋ ์์ ํ๊ฐ?"์ ๋ต์ ๋๋ถ๋ถ "๊ณต์ ๋๋๊ฐ?" ์ ๊ฐ๋ค.
์๊ธฐ ์ ๊ฒ
์ ์ ์ง์: Unit 1.2
ํต์ฌ ๊ฐ๋
์ค์ผ์ค๋ง ํ:
์ปจํ ์คํธ ์ค์์นญ(Context Switching):
์๊ธฐ ์ ๊ฒ
๋ชฉํ: 4๊ฐ์ง ์ฉ์ด๊ฐ ๋ฉด์ ์์ ์์ฃผ ํท๊ฐ๋ฆฌ๋๋ฐ, "๋ฌด์์ด ๋ค๋ฅธ ์ถ์ธ๊ฐ" ๋ฅผ ๋ช ํํ ์ก๋๋ค.
์ ์ ์ง์: Phase 1
ํต์ฌ ๊ฐ๋
ํต์ฌ ์ง๋ฌธ: "๋ค์ ์์ ์ ์ํด ์ด์ ์์ ์ ์๋ฃ ์ฌ๋ถ๋ฅผ ํ์ธ ํ๋๊ฐ?"
์๊ธฐ ์ ๊ฒ
์ ์ ์ง์: Unit 2.1
ํต์ฌ ๊ฐ๋
ํต์ฌ ์ง๋ฌธ: "OS(๋๋ ํธ์ถ๋ ํจ์)๊ฐ ์ ์ด๊ถ์ ๊ฐ์ ธ๊ฐ๋๊ฐ, ์ฆ์ ๋๋ ค์คฌ๋๊ฐ?"
์ ์ด๊ถ์ ์๋ฏธ:
์๊ธฐ ์ ๊ฒ
์ ์ ์ง์: Unit 2.1, Unit 2.2
ํต์ฌ ๊ฐ๋
| Blocking | Non-Blocking | |
|---|---|---|
| Sync | ๊ฐ์ฅ ๋จ์ (์ ํต IO) | Polling ๋ฐฉ์ |
| Async | Future.get() | CompletableFuture, Callback |
4๊ฐ์ง ์กฐํฉ ์ ๋ฆฌ:
Socket.read())socketChannel.read() ๊ฐ 0 ๋ฐํ ์ ๋ค๋ฅธ ์ผFuture.get()CompletableFuture์๊ธฐ ์ ๊ฒ
๋ชฉํ: ์ค๋ ๋๋ฅผ ์ง์ ๋ง๋ค๊ณ ์ํ๋ฅผ ์ถ์ ํ๋ฉฐ ์ ์ดํ๋ค.
์ ์ ์ง์: Phase 1
ํต์ฌ ๊ฐ๋
NEW โโstart()โโ> RUNNABLE โโ์์
์ข
๋ฃโโ> TERMINATED
โ โโ (CPU ์ค์ผ์ค๋ฌ)
โ
โโโโโโโโโโโผโโโโโโโโโโโโโโ
โ โ โ
BLOCKED WAITING TIMED_WAITING
(synchronized) (wait, join) (sleep, parkNanos)
์ํ ์ ์ด:
NEW โ RUNNABLE: start() ํธ์ถRUNNABLE โ BLOCKED: synchronized ๋ฝ ๋๊ธฐRUNNABLE โ WAITING: wait(), join()RUNNABLE โ TIMED_WAITING: sleep(ms), wait(ms)* โ TERMINATED: run ์ข
๋ฃ์๊ธฐ ์ ๊ฒ
getState()๋ RUNNING์ ๋ฐํํ ์ ์๋๊ฐ?์ ์ ์ง์: Unit 3.1
ํต์ฌ ๊ฐ๋
Thread ํด๋์ค ์์ โ run() ์ค๋ฒ๋ผ์ด๋start() ํธ์ถ๋ก ์ค์ ์ค๋ ๋ ์์run()์ ์ง์ ํธ์ถํ๋ฉด ์ ์ค๋ ๋๊ฐ ์๊ธฐ์ง ์์ (๊ทธ๋ฅ ๋ฉ์๋ ํธ์ถ)class MyThread extends Thread {
public void run() {
System.out.println("Thread running");
}
}
new MyThread().start(); // ์ ์ค๋ ๋์์ ์คํ โ
new MyThread().run(); // ํ์ฌ ์ค๋ ๋์์ ์คํ โ
์๊ธฐ ์ ๊ฒ
run() ์ง์ ํธ์ถ๊ณผ start() ํธ์ถ์ ์ฐจ์ด๋ฅผ ์ค๋ ๋ ์ํ๋ก ์ค๋ช
ํ๋ผstart()๋ฅผ ๋ ๋ฒ ํธ์ถํ๋ฉด?์ ์ ์ง์: Unit 3.2
ํต์ฌ ๊ฐ๋
Thread ์์์ ํ๊ณ:
Runnable์ ์ฅ์ 3๊ฐ์ง:
1. ๋ค๋ฅธ ํด๋์ค ์์ ๊ฐ๋ฅ (์๋ฐ ๋จ์ผ ์์ ์ ์ฝ ํํผ)
2. ์์
๊ณผ ์ค๋ ๋ ๋ถ๋ฆฌ (๊ฐ์ฒด์งํฅ์ ์ค๊ณ)
3. ๋ฉ๋ชจ๋ฆฌ ํจ์จ (์ฌ๋ฌ ์ค๋ ๋๊ฐ ๊ฐ์ Runnable ๊ณต์ ๊ฐ๋ฅ)
Runnable task = () -> System.out.println("Task");
new Thread(task).start();
new Thread(task).start(); // ๊ฐ์ ์์
์ 2๊ฐ ์ค๋ ๋๊ฐ ์คํ
์๊ธฐ ์ ๊ฒ
@Async๋ ๋ด๋ถ์ ์ผ๋ก Thread vs Runnable ์ค ๋ฌด์์ ์ธ๊น?์ ์ ์ง์: Unit 3.3
ํต์ฌ ๊ฐ๋
setDaemon(true) ๋ก ์ค์ (start() ์ ์)์ฉ๋: GC ์ค๋ ๋, ๋ชจ๋ํฐ๋ง, ๋ก๊น ๋ฑ ๋ฐฑ๊ทธ๋ผ์ด๋ ๋ณด์กฐ ์์
์ฃผ์: ์์ ์๋ฃ ๋ณด์ฅ์ด ํ์ํ๋ฉด ๋ฐ๋ชฌ์ผ๋ก ์ค์ ๊ธ์ง
์๊ธฐ ์ ๊ฒ
์ ์ ์ง์: Unit 3.4
ํต์ฌ ๊ฐ๋
t.join(): t ์ค๋ ๋๊ฐ ์ข
๋ฃ๋ ๋๊น์ง ํ์ฌ ์ค๋ ๋๋ฅผ ๋๊ธฐ๋ณ๋ ฌ ์คํ vs ์ง๋ ฌ ์คํ:
// ๋ณ๋ ฌ (3์ด)
t1.start(); t2.start();
t1.join(); t2.join();
// ์ง๋ ฌ (5์ด) โ ์๋ชป๋ ํจํด
t1.start(); t1.join();
t2.start(); t2.join();
์๊ธฐ ์ ๊ฒ
join() ํธ์ถ ์ ํธ์ถ์ ์ค๋ ๋์ ์ํ๋?๋ชฉํ: ๋ฉํฐ์ค๋ ๋์ ๊ฐ์ฅ ํฐ ์ ์ธ ๋ฐ์ดํฐ ๋ถ์ผ์น ๋ฅผ ๋ง๋ ๊ฐ์ฅ ๊ธฐ๋ณธ ๋๊ตฌ๋ฅผ ๋ง์คํฐํ๋ค.
์ ์ ์ง์: Phase 3
ํต์ฌ ๊ฐ๋
๊ณ ์ ์ ์์ :
class Counter {
int count = 0;
void increment() { count++; } // โ ์๊ณ ์์ญ
}
count++ ๋ ์ฌ์ค ์ฝ๊ธฐ โ 1 ๋ํ๊ธฐ โ ์ฐ๊ธฐ 3๋จ๊ณ โ ๋ ์ค๋ ๋๊ฐ ๋์ ์คํ ์ ๊ฒฐ๊ณผ ์์ค
์๊ธฐ ์ ๊ฒ
count++ ์ ์ด์
๋ธ๋ฆฌ ์์ค ๋์์ ์ค๋ช
ํด๋ณด๋ผ์ ์ ์ง์: Unit 4.1
ํต์ฌ ๊ฐ๋
synchronized ํค์๋this (ํด๋น ์ธ์คํด์ค)class Counter {
private int count = 0;
public synchronized void increment() {
count++;
}
}
์๊ธฐ ์ ๊ฒ
Class ๊ฐ์ฒด)์ ์ ์ง์: Unit 4.2
ํต์ฌ ๊ฐ๋
public void increment() {
// ๋น๋๊ธฐ ์์ญ
synchronized (this) { // โ ์๊ณ ์์ญ๋ง ์ ๊ธ
count++;
}
// ๋น๋๊ธฐ ์์ญ
}
์ ํ ๊ฐ์ด๋:
synchronized ๋ฉ์๋synchronized ๋ธ๋ก (์ฑ๋ฅ โ)์๊ธฐ ์ ๊ฒ
synchronized (this) ์ synchronized (new Object()) ์ ์ฐจ์ด๋?์ ์ ์ง์: Unit 4.3
ํต์ฌ ๊ฐ๋
๋ฝ ๊ฒฝ์ ์๋๋ฆฌ์ค:
synchronized์ ๋จ์ :
์๊ธฐ ์ ๊ฒ
์ ์ ์ง์: Unit 4.4
ํต์ฌ ๊ฐ๋
๋ฌธ์ ์๋๋ฆฌ์ค:
boolean runFlag = true;
// ์ค๋ ๋ A: while (runFlag) { ... }
// ์ค๋ ๋ B: runFlag = false;
// โ A๊ฐ ์์ํ ์ข
๋ฃ ์ ๋จ!
์์ธ: ๊ฐ CPU ์ฝ์ด๋ ์๊ธฐ ์บ์ ๋ฉ๋ชจ๋ฆฌ ๋ฅผ ์ฌ์ฉ
false ๋ณ๊ฒฝ์ด ๋ฉ์ธ ๋ฉ๋ชจ๋ฆฌ์ ๋ฐ์ ์ ๋จtrueํด๊ฒฐ: volatile:
volatile boolean runFlag = true;
์ค์: synchronized ์์ ๋ณ์๋ ์๋์ผ๋ก ๊ฐ์์ฑ ๋ณด์ฅ๋จ
์๊ธฐ ์ ๊ฒ
volatile์ด ์์์ฑ๋ ๋ณด์ฅํ๋๊ฐ? (ํํธ: NO. count++๋ ์ฌ์ ํ ์ํ)volatile๊ณผ synchronized์ ์ฐจ์ด๋ฅผ ํ ๋ฌธ์ฅ์ผ๋ก?๋ชฉํ: synchronized์ ํ๊ณ๋ฅผ ReentrantLock์ผ๋ก ๊ทน๋ณตํ๊ณ , ๋ฐ๋๋ฝ์ ํํผํ๋ ํจํด์ ์ตํ๋ค.
์ ์ ์ง์: Phase 4
ํต์ฌ ํ๊ณ 3๊ฐ์ง:
1. ๋ฌดํ ๋๊ธฐ: ํ์์์ ์ค์ ๋ถ๊ฐ
2. ์ธํฐ๋ฝํธ ๋ถ๊ฐ: ๋๊ธฐ ์ค ์ธ๋ถ์์ ๊นจ์ธ ์ ์์
3. ๊ณต์ ์ฑ X: ์ด๋ค ์ค๋ ๋๊ฐ ๋ฝ์ ๋ฐ์์ง ๋ณด์ฅ ์์
ํด๊ฒฐ์ฑ : ์๋ฐ๋ ๋ ์ ๊ตํ ๋ฝ ๋๊ตฌ๋ฅผ ์ ๊ณต
์๊ธฐ ์ ๊ฒ
์ ์ ์ง์: Unit 5.1
ํต์ฌ ๊ฐ๋
LockSupport์ 3๊ฐ์ง ๋ฉ์๋:
park(): ํ์ฌ ์ค๋ ๋๋ฅผ WAITING ์ํ๋ก (์ฃผ์ฐจ)parkNanos(nanos): TIMED_WAITING ์ํ๋ก (์๊ฐ ํ์ )unpark(thread): ๋์ ์ค๋ ๋๋ฅผ RUNNABLE๋ก ๋ณต๊ทThread t = new Thread(() -> {
LockSupport.park();
System.out.println("๊นจ์ด๋จ");
});
t.start();
Thread.sleep(100);
LockSupport.unpark(t); // ๊นจ์
ํน์ง:
์๊ธฐ ์ ๊ฒ
์ ์ ์ง์: Unit 5.2
ํต์ฌ ๊ฐ๋
Lock ์ธํฐํ์ด์ค์ ๊ตฌํ์ฒด (java.util.concurrent.locks)try-finally ํ์ (๋ฝ ๋ฐ๋ฉ ๋ณด์ฅ)private final Lock lock = new ReentrantLock();
public boolean withdraw(int amount) {
lock.lock(); // ๋ฝ ํ๋
try {
// ์๊ณ ์์ญ
balance -= amount;
return true;
} finally {
lock.unlock(); // ๋ฐ๋์ finally์์!
}
}
์ finally๊ฐ ํ์์ธ๊ฐ:
์๊ธฐ ์ ๊ฒ
lock() ๊ณผ synchronized ์ ์ฐจ์ด๋ฅผ ํ ๋ฌธ์ฅ์ผ๋ก?unlock() ์ ๊น๋ฐํ๋ฉด ์ด๋ค ์ฌ๊ณ ๊ฐ?์ ์ ์ง์: Unit 5.3
ํต์ฌ ๊ฐ๋
tryLock()์ ๋ ํํ:
boolean tryLock(): ์ฆ์ ์๋, ์คํจ ์ falseboolean tryLock(time, unit): ์ง์ ์๊ฐ๋งํผ ์๋if (!lock.tryLock()) {
log("์ด๋ฏธ ์ฒ๋ฆฌ์ค์ธ ์์
์ด ์์ต๋๋ค.");
return false; // ๋ฌดํ ๋๊ธฐ ์ ํจ
}
try {
// ์๊ณ ์์ญ
} finally {
lock.unlock();
}
๋ฐ๋๋ฝ ํํผ ์๋๋ฆฌ์ค:
lock() ์ด๋ฉด ์์ํ ๋ฉ์ถคtryLock() ์ด๋ฉด ํ ์ชฝ์ด ํฌ๊ธฐํ๊ณ ์ฌ์๋ โ ๋ฐ๋๋ฝ ํํผ์๊ธฐ ์ ๊ฒ
lock() ๋ง ์ฐ๋ ์์คํ
์์ ๋ฐ๋๋ฝ์ด ๋ฐ์ํ๋ฉด ์ด๋ป๊ฒ ํ๋ณตํ๋๊ฐ?tryLock(5, SECONDS) ๊ฐ ์คํจํ ํ ์ด๋ค ์ ๋ต์ ์ธ ์ ์๋?๋ชฉํ: ์ค๋ ๋๋ค์ด ๋จ์ํ ๊ฒฝ์ํ๋ ๊ฒ์ด ์๋๋ผ ํ๋ ฅ ํ๋ ํจํด์ ์ตํ๋ค.
์ ์ ์ง์: Phase 4
ํต์ฌ ๊ฐ๋
๋ฌธ์ ์ ์:
์ค์ ์ฌ๋ก: ๋ฉ์์ง ํ(MQ), ๋ก๊น ์์คํ , ์์ ํ
์๊ธฐ ์ ๊ฒ
์ ์ ์ง์: Unit 6.1
ํต์ฌ ๊ฐ๋
wait(): synchronized ์์์ ํธ์ถ โ ๋ฝ์ ๋ฐ๋ฉํ๊ณ WAITING ์ํ๋กnotify(): WAITING ์ค์ธ ์ค๋ ๋ 1๊ฐ๋ฅผ ๊นจ์notifyAll(): ๋ชจ๋ WAITING ์ค๋ ๋๋ฅผ ๊นจ์synchronized (lock) {
while (queue.isEmpty()) {
lock.wait(); // ๋ฝ ๋ฐ๋ฉ + ๋๊ธฐ
}
// ๋ฐ์ดํฐ ์ฒ๋ฆฌ
lock.notify(); // ๋ค๋ฅธ ์ค๋ ๋ ๊นจ์
}
์ if๊ฐ ์๋๋ผ while?:
์๊ธฐ ์ ๊ฒ
wait()๊ณผ sleep()์ ๊ฒฐ์ ์ ์ฐจ์ด๋? (ํํธ: ๋ฝ)notify()์ notifyAll() ์ค ์ด๋ ๊ฒ์ ๊ถ์ฅ? (ํํธ: ์์ ์ฑ)์ ์ ์ง์: Phase 3
ํต์ฌ ๊ฐ๋
3๊ฐ์ง ๋ฉ์๋ ๊ตฌ๋ถ:
| ๋ฉ์๋ | ๋์ | ํ๋๊ทธ ๋ณํ |
|---|---|---|
interrupt() | ์ธํฐ๋ฝํธ ์ ํธ ๋ฐ์ก | true๋ก ์ค์ |
isInterrupted() | ํ๋๊ทธ ํ์ธ (๋ณ๊ฒฝ X) | ๋ณํ ์์ |
interrupted() (static) | ํ๋๊ทธ ํ์ธ ํ false๋ก | true โ false |
๋ธ๋กํน ๋ฉ์๋์ ๋์:
sleep(), wait(), join() ์ค์ ์ธํฐ๋ฝํธ ๋ฐ์ผ๋ฉดInterruptedException ๋ฐ์์ฆ๊ฐ ์ข ๋ฃ ํจํด:
while (!Thread.interrupted()) { // ๋งค๋ฒ ํ๋๊ทธ ์ฒดํฌ
// ์ผ ์ํ
}
์๊ธฐ ์ ๊ฒ
interrupt() ๋ง ํธ์ถํ๋๋ฐ ์ค๋ ๋๊ฐ ์ฆ์ ์ข
๋ฃ ์ ๋๋ ์ด์ ๋?sleep() ๋์ค ์ธํฐ๋ฝํธ๊ฐ ๋ค์ด์ค๋ฉด ์ด๋ป๊ฒ ๋๋๊ฐ?์ ์ ์ง์: Unit 6.3
ํต์ฌ ๊ฐ๋
yield(): "๋ค๋ฅธ ์ค๋ ๋์ CPU๋ฅผ ์๋ณดํ๊ฒ ๋ค"๋ ํํธ์ฉ๋: ๋ฐ์ ๋๊ธฐ(Busy Waiting) ์ํฉ์์ CPU ์์ ์ ์ฝ
while (!Thread.interrupted()) {
if (queue.isEmpty()) {
Thread.yield(); // CPU ์๋ณด
continue;
}
// ์์
}
์ํ ๋น๊ต:
| ๋ฉ์๋ | ๊ฒฐ๊ณผ ์ํ |
|---|---|
| sleep() | RUNNABLE โ TIMED_WAITING โ RUNNABLE |
| yield() | RUNNABLE โ RUNNABLE (์ ๊น ์๋ณด) |
| wait() | RUNNABLE โ WAITING โ RUNNABLE |
์๊ธฐ ์ ๊ฒ
yield() ๊ฐ OS์ ๋ณด์ฅ๋ ๋์์ธ๊ฐ? (ํํธ: ๋จ์ ํํธ)๋ชฉํ: ์ค๋ ๋ ์ง์ ์ฌ์ฉ์ ๋ชจ๋ ํ๊ณ๋ฅผ ํ ๋ฒ์ ํด๊ฒฐํ๋ ์๋ฐ ํ์ค ๋์์ฑ ๋๊ตฌ๋ฅผ ๋ง์คํฐํ๋ค.
์ ์ ์ง์: Phase 3 ~ 6
ํต์ฌ ๋ฌธ์ :
์์ฑ ๋น์ฉ:
๊ด๋ฆฌ ๋ฌธ์ :
Runnable์ ๋ถํธํจ:
void run())ํด๊ฒฐ์ฑ = ์ค๋ ๋ ํ + ๋ฐํ๊ฐ ๊ฐ๋ฅํ ์์ ์ธํฐํ์ด์ค = Executor ํ๋ ์์ํฌ
์๊ธฐ ์ ๊ฒ
์ ์ ์ง์: Unit 7.1
ํต์ฌ ๊ฐ๋
3๊ฐ ํ์ ์ ์ญํ ๋ถ๋ด:
| ์ด๋ฆ | ์ญํ |
|---|---|
Executor (์ธํฐํ์ด์ค) | ์์
์คํ๋ง (execute(Runnable)) |
ExecutorService (์ธํฐํ์ด์ค) | + ์์
์ ์ด (submit, shutdown, invokeAll) |
Executors (์ ํธ ํด๋์ค) | ExecutorService ํฉํ ๋ฆฌ |
๊ด๊ณ:
Executor (์คํ๋ง)
โโ ExecutorService (์คํ + ์ ์ด)
โ ์์ฑ
โโ Executors.newFixedThreadPool() ๋ฑ
์๊ธฐ ์ ๊ฒ
Executor ์ ExecutorService ๋ฅผ ๋ถ๋ฆฌํ ์ด์ ๋? (ํํธ: ISP)new ThreadPoolExecutor(...) ๋์ Executors.xxx() ๋ฅผ ์ฐ๋?์ ์ ์ง์: Unit 7.2
ํต์ฌ ๊ฐ๋
| ํฉํ ๋ฆฌ ๋ฉ์๋ | ํน์ง | ์ ํฉ ์ํฉ |
|---|---|---|
newFixedThreadPool(n) | ๊ณ ์ n๊ฐ ์ค๋ ๋ | ์ผ๋ฐ ์๋ฒ, ์์ ์ฑ ์ฐ์ |
newCachedThreadPool() | ํ์ ์ ๋ฌดํ ์์ฑ, 60์ด ํ ํ์ | ์งง์ ์์ ๋ค์ |
newSingleThreadExecutor() | 1๊ฐ ์ค๋ ๋ | ์์ ๋ณด์ฅ ํ์ |
newScheduledThreadPool(n) | ์ฃผ๊ธฐ์ /์ง์ฐ ์คํ | ์ค์ผ์ค๋ฌ, ๋ฐฐ์น |
์ค์ ์ฃผ์:
newCachedThreadPool() ์ ํธ๋ํฝ ํญ์ฃผ ์ ์ํ (์ค๋ ๋ ํญ์ฆ)์๊ธฐ ์ ๊ฒ
์ ์ ์ง์: Unit 7.3
ํต์ฌ ๊ฐ๋
Runnable vs Callable:
| ํญ๋ชฉ | Runnable | Callable |
|---|---|---|
| ๋ฉ์๋ | void run() | V call() throws Exception |
| ๋ฐํ๊ฐ | โ | โ (์ ๋ค๋ฆญ) |
| ์ฒดํฌ ์์ธ | โ | โ |
Future:
submit() ์ ๋ฐํ ํ์
get() ์ผ๋ก ๊ฒฐ๊ณผ ํ์ (๋ธ๋กํน)ExecutorService es = Executors.newFixedThreadPool(2);
Future<Integer> future = es.submit(() -> {
Thread.sleep(2000);
return 42;
});
log("future ์ฆ์ ๋ฐํ (์์
์ ๋ฐฑ๊ทธ๋ผ์ด๋์์ ์งํ)");
Integer result = future.get(); // ์ฌ๊ธฐ์ ๋ธ๋กํน
์๊ธฐ ์ ๊ฒ
submit() ํธ์ถ ์ฆ์ Future๊ฐ ๋ฐํ๋๋๋ฐ, ์์
์ ์ด๋์ ์คํ๋๋๊ฐ?future.get() ํธ์ถ ์ ์ ์์
์ด ์ด๋ฏธ ๋๋ฌ๋ค๋ฉด?์ ์ ์ง์: Unit 7.4
ํต์ฌ ๊ฐ๋
cancel(mayInterruptIfRunning):
true: ์คํ ์ค์ธ ์์
์ ์ธํฐ๋ฝํธ ๋ฐ์ โ ์ฆ์ ์ค๋จ ์๋false: ์คํ ์ค์ด๋ฉด ๊ทธ๋ฅ ๋ , ์๋ก ์คํ์ ์ ํจ์ดํ get() ํธ์ถ ์ โ CancellationException
์๊ธฐ ์ ๊ฒ
Thread.sleep(1000) ์ค์ธ๋ฐ cancel(true) ํธ์ถ ์ ์ด๋ป๊ฒ ๋๋๊ฐ?cancel(true) ๊ฐ ํจ๊ณผ ์๋๊ฐ?์ ์ ์ง์: Unit 7.5
ํต์ฌ ๊ฐ๋
| ๋ฉ์๋ | ๋์ |
|---|---|
invokeAll(tasks) | ๋ชจ๋ ์์ ์๋ฃ ๊น์ง ๋๊ธฐ, ๋ชจ๋ ๊ฒฐ๊ณผ ๋ฐํ |
invokeAny(tasks) | ์ฒซ ๋ฒ์งธ ์๋ฃ๋ ์์ ์ ๊ฒฐ๊ณผ ๋ฐํ, ๋๋จธ์ง ์ทจ์ |
ํ์ฉ ์๋๋ฆฌ์ค:
invokeAll: ์ฌ๋ฌ ์ธ๋ถ API ํธ์ถ ํ ๋ชจ๋ ๊ฒฐ๊ณผ ์ข
ํฉinvokeAny: ์ฌ๋ฌ ํ๋ณด ์ค ๊ฐ์ฅ ๋นจ๋ฆฌ ์๋ตํ ๊ฒ ์ฑํ (์: ๋ฏธ๋ฌ ์๋ฒ)์๊ธฐ ์ ๊ฒ
invokeAll ๋์ค ํ ์์
์ด ์์ธ๋ฅผ ๋์ง๋ฉด?invokeAny ๊ฐ ๊ฐ์ฅ ๋น ๋ฅธ ์๋ต์ ์ด๋ป๊ฒ ๊ฒฐ์ ํ๋๊ฐ?์ ์ ์ง์: Unit 7.6
ํต์ฌ ๊ฐ๋
| ๋ฉ์๋ | ์ ์์ ๊ฑฐ์ | ์งํ ์ค ์์ | ํ์ ์์ |
|---|---|---|---|
shutdown() | โ | ๋ง๋ฌด๋ฆฌ | ๋ง๋ฌด๋ฆฌ |
shutdownNow() | โ | ์ธํฐ๋ฝํธ | ํฌ๊ธฐ (๋ฐํ๋จ) |
์์ ์ข ๋ฃ ํจํด:
es.shutdown();
if (!es.awaitTermination(60, SECONDS)) {
es.shutdownNow(); // 60์ด ๋ด ์ ๋๋๋ฉด ๊ฐ์
}
์๊ธฐ ์ ๊ฒ
shutdownNow() ๊ฐ ๋ฐํํ๋ List์๋ ๋ฌด์์ด ๋ด๊ธฐ๋๊ฐ?๋ชฉํ: Future์ ํ๊ณ(๋ธ๋กํน ํ์)๋ฅผ ๋๋ ์ง์ ํ ๋น๋๊ธฐ + ๋ณ๋ ฌ ์ฒ๋ฆฌ ๋๊ตฌ๋ฅผ ์ตํ๋ค.
์ ์ ์ง์: Unit 7.4
Future์ ํ๊ณ:
future.get())CompletableFuture์ ํด๊ฒฐ:
thenApply, thenAccept, thenCombine ๋ฑ ์ฒด์ด๋CompletableFuture.supplyAsync(() -> 5)
.thenApply(x -> x * 2) // ๋ณํ
.thenCombine(otherFuture, Integer::sum) // ๊ฒฐํฉ
.thenAccept(System.out::println); // ์๋น
System.out.println("Main thread continues..."); // ์ฆ์ ์คํ
์๊ธฐ ์ ๊ฒ
Future.get() ๊ณผ CompletableFuture.thenAccept() ์ ๋ณธ์ง์ ์ฐจ์ด๋?์ ์ ์ง์: Phase 7
ํต์ฌ ๊ฐ๋
์ผ๋ฐ ์ค๋ ๋ ํ์ ํ๊ณ:
ForkJoinPool์ ์์ด๋์ด:
ํจ๊ณผ: ๋ชจ๋ ์ค๋ ๋๊ฐ ์ด ํ ์์ด ์ผํจ โ CPU ์ฌ์ฉ๋ฅ ๊ทน๋ํ
์๊ธฐ ์ ๊ฒ
์ ์ ์ง์: Unit 8.2
ํต์ฌ ๊ฐ๋
| ํด๋์ค | ๋ฐํ๊ฐ |
|---|---|
RecursiveTask<V> | ์์ (V) |
RecursiveAction | ์์ (void) |
๊ตฌํ ํจํด:
1. compute() ์ค๋ฒ๋ผ์ด๋
2. ์์
์ด ์์ผ๋ฉด ์ง์ ์ฒ๋ฆฌ
3. ํฌ๋ฉด ๋๋ก ๋๋ ์:
leftTask.fork() (๋น๋๊ธฐ ์์)rightResult = rightTask.compute() (๋๊ธฐ ์ฒ๋ฆฌ)leftResult = leftTask.join() (๋๊ธฐ ํ ํฉ์ฐ)class SumTask extends RecursiveTask<Long> {
protected Long compute() {
if (์์
์ด ์์ผ๋ฉด) return ์ง์ ๊ณ์ฐ();
SumTask left = new SumTask(start, mid);
SumTask right = new SumTask(mid+1, end);
left.fork();
long r = right.compute();
long l = left.join();
return l + r;
}
}
์๊ธฐ ์ ๊ฒ
fork() ์ compute() ๋ฅผ ๋์์ ํธ์ถํ์ง ์๊ณ ๋๋ ์ฐ๋ ์ด์ ๋?parallelStream() ์ ๋ด๋ถ์ ์ผ๋ก ๋ฌด์์ ์ฌ์ฉํ๋๊ฐ?start() ์ run() ์ ์ฐจ์ด๋?lock() ๋ค์์ ๋ฐ๋์ try-finally ๊ฐ ํ์ํ ์ด์ ๋?tryLock() ์ด ๋ฐ๋๋ฝ์ ์ด๋ป๊ฒ ๋ฐฉ์งํ๋๊ฐ?wait() ๊ฐ synchronized ์์์๋ง ๋์ํ๋ ์ด์ ๋?interrupt(), interrupted(), isInterrupted() ์ ์ฐจ์ด๋?yield() ์ sleep() ์ ์ํ ์ฐจ์ด๋?newCachedThreadPool() ์ ์ํ์ฑ์?Future.get() ๊ณผ CompletableFuture.thenAccept() ์ ์ฐจ์ด๋?shutdown() ๊ณผ shutdownNow() ์ค ์์ ์ข
๋ฃ์ ์ ํฉํ ๊ฒ์?๋ฐ๋์ ๊น์ด ํ๊ธฐ (๋ฉด์ ยท์ค๋ฌด ์ง๊ฒฐ):
[ ] Phase 1 โ ๋์์ฑ ๊ธฐ์ด (Unit 1.1~1.4)
[ ] Phase 2 โ 4๋ถ๋ฉด ๋งคํธ๋ฆญ์ค (Unit 2.1~2.3)
[ ] Phase 3 โ ์ค๋ ๋ ๋ค๋ฃจ๊ธฐ (Unit 3.1~3.5)
[ ] Phase 4 โ synchronized & volatile (Unit 4.1~4.5) โ
1์ฐจ ์ ์
[ ] Phase 5 โ Lock ๋๊ตฌ (Unit 5.1~5.4)
[ ] Phase 6 โ ์ค๋ ๋ ํ๋ ฅ (Unit 6.1~6.4)
[ ] Phase 7 โ Executor ํ๋ ์์ํฌ (Unit 7.1~7.7) โ
2์ฐจ ์ ์
[ ] Phase 8 โ ๊ณ ๊ธ ๋น๋๊ธฐ (Unit 8.1~8.3)
[ ] ์ข
ํฉ ์๊ธฐ ์ ๊ฒ 31๋ฌธํญ ํต๊ณผ
ํ์ ์ค์ต ์ฝ๋:
1. Race condition ์ง์ ์ฌํ (synchronized ์๋ ์นด์ดํฐ ์ฆ๊ฐ)
2. ๋ฐ๋๋ฝ ์๋๋ฆฌ์ค (๋ฝ 2๊ฐ ์ก๋ ๋ ์ค๋ ๋)
3. wait/notify๋ก ์์ฐ์-์๋น์ ๊ตฌํ
4. ExecutorService๋ก ๊ฐ์ ์์
์ ํ๋ก ์ฒ๋ฆฌ
5. CompletableFuture ์ฒด์ด๋ (3๊ฐ API ํธ์ถ ํฉ์น๊ธฐ)
๋๋ฒ๊น ๋๊ตฌ:
jstack <pid>: ์ค๋ ๋ ๋คํ (BLOCKED/WAITING ํ์ธ)-XX:+PrintGCDetails: GC์ ์ค๋ ๋์ ์ํธ์์ฉ