๋์์ฑ๊ณผ ๊น๋ํ ์ฝ๋๋ ์๋ฆฝํ๊ธฐ ์์ฃผ ์ด๋ ต๋ค. ๊ทธ๋ผ์๋ ๋ถ๊ตฌํ๊ณ , ๋์์ฑ์ ์ ํ์ํ ๊น?
๊ฐ์ฒด๋ ์ฒ๋ฆฌ์ ์ถ์ํ๋ค. ์ค๋ ๋๋ ์ผ์ ์ ์ถ์ํ๋ค. - ์ ์์ค O. ์ฝํ๋ฆฌ์
๋์์ฑ์ด ํ์ํ ์ด์ ?
๋์์ฑ์ โ๋ฌด์โ๊ณผ โ์ธ์ โ์ Coupling์ ์์ ๋ ์ ๋ต์ด๋ค.
์ค๋ ๋๊ฐ ํ๋์ธ ํ๋ก๊ทธ๋จ์, ๋ฌด์๊ณผ ์ธ์ ๊ฐ ๋ฐ์ ํ๊ธฐ ๋๋ฌธ์, call stack์ ์ดํด๋ณด๋ฉด ํด๋น ํ๋ก๊ทธ๋จ์ ์ํ๋ฅผ ๋ฐ๋ก ํ์ ํ ์ ์๋ค. ํ์ง๋ง, ๋ฌด์๊ณผ ์ธ์ ๋ฅผ ๋ถ๋ฆฌํ๋ฉด ์ ํ๋ฆฌ์ผ์ด์ ๊ตฌ์กฐ์ ํจ์จ์ด ๊ทน์ ์ผ๋ก ๋์์ง๋ค. ๊ฑฐ๋ํ ํ๋์ ๋ฃจํ๊ฐ ์๋๋ผ, ์์ ํ๋ ฅ ํ๋ก๊ทธ๋จ ์ฌ๋ฟ์ด ๋ฌธ์ ๋ฅผ ํธ๋ ๊ฒ์ผ๋ก ์๊ฐํ ์ ์๋ค. ์๋ฅผ ๋ค์ด, java Subvlet ๋ชจ๋ธ์ ๊ฒฝ์ฐ, ์น ์์ฒญ์ด ๋ค์ด์ฌ ๋๋ง๋ค ์น ์๋ฒ๋ ๋น๋๊ธฐ์์ผ๋ก ์๋ธ๋ฆฟ์ ์คํํ๋ค.
์ด๋ฐ ๊ตฌ์กฐ์ ์ธ ์ด์ ๋ง์ ์ํด ๋์์ฑ์ ์ฑํํ๋ ๊ฒ์ ์๋๋ค. ์๋ต ์๊ฐ, ์์ ์ฒ๋ฆฌ๋ ๊ฐ์ ์ด๋ผ๋ ์๊ตฌ์ฌํญ์ผ๋ก ์ธํด ๋์์ฑ ๊ตฌํ์ ๋ถ๊ฐํผํ๊ฒ ์ ํํด์ผ ํ๋ ๊ฒฝ์ฐ๋ ์๋ค.
๋ฏธ์ ๊ณผ ์คํด
์ค๊ฐ๋ | ํด์ค |
---|---|
๋์์ฑ์ ํญ์ ์ฑ๋ฅ์ ๋์ฌ์ค๋ค. | ๋๋๋ก ์ฑ๋ฅ์ ๋์ฌ์ค๋ค. ์ฌ๋ฌ ํ๋ก์ธ์๊ฐ ๋์์ ์ฒ๋ฆฌํ ๊ณ์ฐ์ด ์ถฉ๋ถํ ๋ง์ ๊ฒฝ์ฐ, ๋๊ธฐ ์๊ฐ์ด ๊ธด ๊ฒฝ์ฐ๊ฐ ์๊ฐ ๋ ์ ์๋ค. |
๋์์ฑ์ ๊ตฌํํด๋ ์ค๊ณ๋ ๋ณํ์ง ์๋๋ค. | ๋จ์ผ ์ค๋ ๋ ์์คํ ๊ณผ ๋ค์ค ์ค๋ ๋ ์์คํ ์ ์ค๊ณ๊ฐ ํ์ดํ๊ฒ ๋ค๋ฅด๋ค. |
์น ๋๋ EJB ์ปจํ ์ด๋๋ฅผ ์ฌ์ฉํ๋ฉด ๋์์ฑ์ ์ดํดํ ํ์๊ฐ ์๋ค. | ์ปจํ ์ด๋๊ฐ ์ด๋ป๊ฒ ๋์ํ๋์ง, ์ด๋ป๊ฒ ๋์ ์์ , ๋ฐ๋๋ฝ๊ณผ ๊ฐ์ ๋ฌธ์ ๋ฅผ ํผํ ์ ์๋์ง ์์์ผ ํ๋ค. |
ํ๋นํ ์๊ฐ
ํ๋นํ ์๊ฐ | ํด์ค |
---|---|
๋์์ฑ์ ๋ค์ ๋ถํ๋ฅผ ์ ๋ฐํ๋ค. | ์ฑ๋ฅ ์ธก๋ฉด์์ ๋ถํ๊ฐ ๊ฑธ๋ฆฌ๋ฉฐ, ์ฝ๋๋ ๋ ์ง์ผ ํ๋ค. |
๋์์ฑ์ ๋ณต์กํ๋ค. | ๊ฐ๋จํ ๋ฌธ์ ๋๋ผ๋ ๋์์ฑ์ ๋ณต์กํ๋ค. |
์ผ๋ฐ์ ์ผ๋ก ๋์์ฑ ๋ฒ๊ทธ๋ ์ฌํํ๊ธฐ ์ด๋ ต๋ค. | ์ง์ง ๊ฒฐํจ์ด ์๋๊ณ , ์ผ์์ฑ ๋ฒ๊ทธ๋ก ์ฌ๊ธฐ๊ธฐ ์ฝ๋ค. |
๋์์ฑ์ ๊ตฌํํ๋ ค๋ฉด ํํ ๊ทผ๋ณธ์ ์ธ ์ค๊ณ ์ ๋ต์ ๋ค์ ์๊ฐํด์ผ ํ๋ค. |
๋๊ด
๊ทธ๋ ๋ค๋ฉด ์ ์ด๋ ค์ด ๊ฒ์ผ๊น?
public class ClassWithThreadingProblem {
private int lastIdUsed;
public ClassWithThreadingProblem(int lastIdUsed) {
this.lastIdUsed = lastIdUsed;
}
public int getNextId() {
return ++lastIdUsed;
}
}
public static void main(String args[]) {
final ClassWithThreadingProblem classWithThreadingProblem = new ClassWithThreadingProblem(42); // 1. instance ์์ฑ, ์ด๊ธฐ๊ฐ 42 ์ค์
Runnable runnable = new Runnable() {
public void run() {
classWithThreadingProblem.getNextId();
}
};
Thread t1 = new Thread(runnable); // ๋ ์ค๋ ๋์์ ํธ์ถ โ
Thread t2 = new Thread(runnable); // ๋ ์ค๋ ๋์์ ํธ์ถ โ
t1.start();
t2.start();
}
์ ์ฝ๋๊ฐ ๋ง๋ค ์ ์๋ ๊ฒฐ๊ณผ๋ ์ด 3๊ฐ์ง ์ด๋ค.
- t1์ด 43์, t2๊ฐ 44๋ฅผ ๊ฐ์ ธ๊ฐ๋ค. lastIdUsed๋ 44์ด๋ค.(O)
- t1์ด 44์, t2๊ฐ 43๋ฅผ ๊ฐ์ ธ๊ฐ๋ค. lastIdUsed๋ 44์ด๋ค.(O)
- t1์ด 43์, t2๊ฐ 43๋ฅผ ๊ฐ์ ธ๊ฐ๋ค. lastIdUsed๋ 43์ด๋ค.(X)
์์ getNextId()
๋ฉ์๋๋ 8๊ฐ์ ์๋ฐ byte-code๋ก ๋ณํ๋๋ฉฐ, ์ด๋ฅผ ๋ ์ค๋ ๋์์ ์คํํ๊ฒ ๋๋ฉด ์ด 12,870๊ฐ์ ์ฝ๋ ์กฐํฉ์ ๋ผ ์ ์๋ค. ๊ทธ ์ค ์ผ๋ง ์ ๋๋ ๋ช๋ช ์กฐํฉ์ด ์์ 3๊ฐ์ง ๊ฒฐ๊ณผ ์ค ๋ง์ง๋ง ๊ฒฐ๊ณผ๋ฅผ ๋ณ๊ฒ ๋๋ค.
๋์์ฑ ๋ฐฉ์ด ์์น
๋์์ฑ ์ฝ๋๊ฐ ๋ฐ์ํ๋ ๋ฌธ์ ๋ก๋ถํฐ ์์คํ ์ ๋ฐฉ์ดํ๋ ์์น๊ณผ ๊ธฐ์ ์ ์๊ฐํ๋ค.
๋จ์ผ ์ฑ ์ ์์น(Single Responsibility Principle, SRP)
๋์์ฑ ์ฝ๋๋ ๋ถ๋ฆฌํ์.
SRP๋ ๊ธฐ๋ณธ์ ์ผ๋ก, ๋ฉ์๋/ํด๋์ค/์ปดํฌ๋ํธ๋ฅผ ๋ณ๊ฒฝํ ์ด์ ๊ฐ ํ๋์ด์ด์ผ ํ๋ค๋ ์์น์ด๋ค. ๋์์ฑ์ ๋ณต์ก์ฑ ํ๋๋ง์ผ๋ก๋ ๋ฐ๋ก ๋ถ๋ฆฌํ ์ด์ ๊ฐ ์ถฉ๋ถํ๋ค.
- Concurrency ๊ด๋ จ ์ฝ๋๋ ๊ฐ๋ฐ, ๋ณ๊ฒฝ, ํ๋์ ๋ค๋ฅธ ์ฝ๋์ ๋ถ๋ฆฌ๋ ์๋ช ์ฃผ๊ธฐ๋ฅผ ๊ฐ์ง๋ค.
- Concurrency ๊ด๋ จ ์ฝ๋๋ ๊ทธ ์์ฒด๊ฐ ๊ฐ์ง๋ ์ด๋ ค์(ํ๊ธฐ ํ๋ ๋ฌธ์ )์ด ์๋ค.
- ์๋ชป ์์ฑ๋ concurrency ์ฝ๋๋ ์ฌ๋ฌ ๋ฌธ์ ๋ฅผ ๋ฐ์์ํฌ ์ ์์ผ๋ฉฐ, ์ด๋ ์ถ๊ฐ์ ์ธ ์ฝ๋ ์์ด ํด๊ฒฐ๋๊ธฐ ํ๋ค๋ค.
๋ฐ๋ฆ ์ ๋ฆฌ(Corollary): ์๋ฃ ๋ฒ์๋ฅผ ์ ํํ๋ผ
์๋ฃ๋ฅผ ์บก์ํ ํ๋ผ. ๊ณต์ ์๋ฃ๋ฅผ ์ต๋ํ ์ค์ด๊ณ , ์๊ณ ์์ญ๋ ์ค์ฌ๋ผ.
์์ ์ฝ๋์์ ๋ณด์๋ ๋ฌธ์ ๋ ๊ฐ์ฒด๋ฅผ ๊ณ ์ตํ ์ํ์์, ๋์ผ ํ๋๋ฅผ ์์ ํ๋ ๋ ์ค๋ ๋๊ฐ ์๋ก ๊ฐ์ญํ๊ธฐ ๋๋ฌธ์ ๋ฐ์ํ๋ค. ์ฆ, ์๋ก ๊ฐ์ญํ์ง ๋ชปํ๋๋ก ํ๋ฉด ๋ฌธ์ ๋ ํด๊ฒฐ๋๋ค. ์ด๋ฐ ์ฝ๋์ ๋ถ๋ถ์ ์๊ณ์์ญ์ด๋ผ ํ๋ค. ์ด๋ฐ ์๊ณ์์ญ์ ์๊ฐ ๋ง์์ง ๊ฒฝ์ฐ ๋ค์์ ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋ค.
- ๋ณดํธํ ์๊ณ ์์ญ์ ๋นผ๋จน๋๋ค.
- ๋ชจ๋ ์๊ณ์์ญ์ ์ ๋๋ก ์ฒ๋ฆฌํ๋์ง ํ์ธํ๋๋ผ ๋๊ฐ์ ๋ ธ๋ ฅ๊ณผ ์๊ณ ๋ฅผ ๋ฐ๋ณตํ๋ค.
- ์๊ทธ๋๋ ์ฐพ๊ธฐ ํ๋ ๋ฐ, ๋ง์์ ธ์ ๋ ์ฐพ๊ธฐ ์ด๋ ต๋ค.
๋ฐ๋ฆ ์ ๋ฆฌ: ์๋ฃ ์ฌ๋ณธ์ ์ฌ์ฉํ๋ผ
Copy๋ฅผ ๋ ์ ์ฒ๋ฆฌํ๋ฉด ์์ ํ๋ค.
๊ณต์ ์๋ฃ๋ฅผ ์ฌ์ฉํ์ง ์๋ ๊ฒ์ ์ด๋จ๊น? ์ ์ด์ ๊ณต์ ํ์ง ์์ผ๋ฉด ๋์์ฑ ๋ฌธ์ ๋ ๋ฐ์ํ์ง ์๋๋ค. ์ฝ๊ธฐ ์ ์ฉ์ผ๋ก ๋ณต์ฌํ์ฌ ์ฌ์ฉํ ์ ์๋ค. ๋ฌผ๋ก ๋ณต์ฌ ๋น์ฉ(memory, time)์ด ๋ ๋ค๋ trade-off๊ฐ ์์ง๋ง, ์ ์ฌ์ฉํ๋ฉด ๋งค์ฐ ์ข์ ๋ฐฉ๋ฒ์ด๋ค.
๋ฐ๋ฆ ์ ๋ฆฌ: ์ค๋ ๋๋ ๊ฐ๋ฅํ ๋ ๋ฆฝ์ ์ผ๋ก ๊ตฌํํ๋ผ
๋ ์์ ์ค๋ ๋, ๋ค๋ฅธ ํ๋ก์ธ์์์ ๋์ํด๋ ๋ฌด๋ฐฉํ๋๋ก ์๋ฃ๋ฅผ ๋ ๋ฆฝ์ ์ธ ๋จ์๋ก ๋ถํ ํ๋ผ.
์ค๋ ๋ ๋ด๋ถ์์ ๋์๊ฐ๋ ์ฝ๋๊ฐ ๊ณต์ instance๋ฅผ ์ฌ์ฉํ์ง ์๊ณ , ๋ด๋ถ local ๋ณ์๋ง ์ฌ์ฉํ๋ ๊ฒ๋ ์ข๋ค. ์ด๋ด ๊ฒฝ์ฐ ๋ค๋ฅธ ์ค๋ ๋์ ๋๊ธฐํํ ํ์๊ฐ ์๋ค. ์ฆ, ์์ํจ์๋ก ์ง๋ผ๋ ๋ง์ด๋ค.
๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ดํดํ๋ผ
ํด๋น ๋ถ๋ถ์ java 5๊ธฐ์ค์ผ๋ก ์ค๋ช ํ๊ธฐ ๋๋ฌธ์ ํ์์๋ ๋ถ๋ถ์ ์ ๋ฆฌํ์ง ์์๋ค.
์ค๋ ๋ ํ๊ฒฝ์ ์์ ํ ์ปฌ๋ ์
์ฌ์ฉํ ์ ์๋ ๊ฐ๋ ์์ฃผ๋ก ์ค๋ช ํ๋ค.
๋ฐฉ๋ฒ | ์ค๋ช |
---|---|
Lock | ํ ๋ฉ์๋์์ ์ ๊ทธ๊ณ ๋ค๋ฅธ ๋ฉ์๋์์ ํผ๋ค. |
Semaphore | ์ ํต์ ์ธ ์ธ๋งํฌ์ด(๊ฐฏ์๋ฅผ ์ ์ ์๋ lock)์ ๊ตฌํ์ฒด์ด๋ค. |
CountDownLatch | ๊ธฐ๋ค๋ฆฌ๋ ๋ชจ๋ ์ค๋ ๋๋ค์ ํด์ ํ๊ธฐ ์ ํน์ ํ์์ ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ๋ ๊ฒ์ ๊ธฐ๋ค๋ฆฌ๊ฒ ํ ์ ์๋ lock์ด๋ค. ๋ชจ๋ ์ค๋ ๋๊ฐ ๊ฑฐ์ ๋์์ ์์๋ ์ ์๊ฒ ๋์์ค ์ ์๋ค. |
์คํ ๋ชจ๋ธ์ ์ดํดํ๋ผ
๊ธฐ๋ณธ ์ฉ์ด๋ถํฐ ์ ๋ฆฌํด๋ณด์.
๋ฐฉ๋ฒ | ์ค๋ช |
---|---|
Bound Resources | ํ๊ฒฝ์์ ์ฌ์ฉ๋๋ ๊ณ ์ ๋ ํฌ๊ธฐ์ ์์์ด๋ค. ์์๋ก ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฐ๊ฒฐ, ๊ณ ์ ๋ ํฌ๊ธฐ์ ์ฝ๊ธฐ/์ฐ๊ธฐ ๋ฒํผ๊ฐ ์๋ค. |
Mutual Exclusion | ํ ์์ ์ ๊ณต์ ์์์ ์ ๊ทผํ ์ ์๋ ์ค๋ ๋๋ ๋จ ํ๋์ด๋ค. |
Starvation | ํ ์ค๋ ๋ ํน์ ์ค๋ ๋์ ๊ทธ๋ฃน์ด ๊ธด ์๊ฐ ํน์ ์์ํ ์์ ์ ์ํํ ์ ์๊ฒ ๋๋ค. ์์ ์ ์ฐ์ ๊ถ์ ๊ฐ์ง๋ ์ํ ์๊ฐ์ด ์งง์ ์ค๋ ๋๊ฐ ๋์์ด ์คํ๋๋ค๋ฉด ์ํ ์๊ฐ์ด ๊ธด ์ค๋ ๋๋ ๊ตถ๊ฒ ๋๋ค. |
Deadlock | ๋ ๊ฐ ์ด์์ ์ค๋ ๋๋ค์ด ์๋ก์ ์์ ์ด ๋๋๊ธฐ๋ฅผ ๊ธฐ๋ค๋ฆฐ๋ค. ๊ฐ ์ค๋ ๋๋ ์๋ก๊ฐ ํ์๋ก ํ๋ ์์์ ์ ์ ํ๊ณ ์์ผ๋ฉฐ ํ์ํ ์์์ ์ป์ง ๋ชปํ๋ ์ด์ ๊ทธ ๋๊ตฌ๋ ์์ ์ ๋๋ด์ง ๋ชปํ๊ฒ ๋๋ค. |
Livelock | ๋ ์ค๋ ๋๊ฐ ๋ฝ์ ํด์ ์ ํ๋์ ๋ฌดํ ๋ฐ๋ณตํ๋ ์ํ์ด๋ค. ์ค๋ ๋๋ค์ด ์๋ก ์์ ์ ์ํํ๋ ค๋ ์ค ๋ค๋ฅธ ์ค๋ ๋๊ฐ ์์ ์ค์ธ ๊ฒ์ ์ธ์งํ๊ณ ์๋ก ์๋ณดํ๋ค. ์ด๋ฌํ ๊ณต๋ช ๋๋ฌธ์ ์ค๋ ๋๋ค์ ์์ ์ ๊ณ์ ์ํํ๋ ค ํ์ง๋ง ์ฅ์๊ฐ ํน์ ์์ํ ์์ ์ ์ํํ์ง ๋ชปํ๊ฒ ๋๋ค. |
์์ฐ์-์๋น์(Producer-Consumer)
์์ ๊ทธ๋ฆผ์์ ์๋ชปํ๋ฉด ์์ฐ์๊ฐ ์ ๋ณด๋ฅผ ์์ฐํ ์ดํ, ์๋น์์๊ฒ ์๋ฆผ์ ๋ณด๋์์๋ ๋ถ๊ตฌํ๊ณ ์๋น์๋ ๋ค์ ์์ฐ์์๊ฒ ๋๊ธฐ์ด์ ์ฑ์ฐ๋ผ๋ ์์ฒญ์ ๊ฑธ์ด๋๊ณ ์๋ต์ ๋๊ธฐํ๊ณ ์๋ ์ํฉ์ด ์ด๋๋ ์ ์๋ค.
์ฝ๊ธฐ-์ฐ๊ธฐ(Readers-Writers)
์ฐ๊ธฐ ์์ ์ ์ฒ๋ฆฌํ๋ ๋์ ์ฝ๊ธฐ ์ค๋ ๋๊ฐ ์ฝ์ง ๋ชปํ๊ฒ ํ๋ค๋ฉด, ์ฒ๋ฆฌ์จ์ ์ํฅ์ ๋ฏธ์น๋ค. ์ด๋ฐ ๊ฒฝ์ฐ ๊ธฐ์ ํ์์ด ๋ฐ์ํ ์ ์๋ค. ๋ฐ๋๋ก ์ฝ๊ธฐ ์ค๋ ๋๊ฐ ์ฝ๋ ๋์ ์ฐ๊ธฐ๊ฐ ๊ฐฑ์ ํ๋ ๊ฒ๋ ๋ชปํ๊ฒ ํด์ผ ํ๋ค.
์ด๋ฐ ์ํฉ์์ ์ฝ๊ธฐ ์ค๋ ๋์ ์๊ตฌ์ ์ฐ๊ธฐ ์ค๋ ๋์ ์๊ตฌ๋ฅผ ์ ์ ํ ๋ง์กฑ์ํฌ ํ์๊ฐ ์๋ค.
์์ฌํ๋ ์ฒ ํ์๋ค(Dining Philosophers)
์ํ์ ๋๋ฌ์ผ ์ฌ๋ฌ ๋ช ์ ์ฒ ํ์๋ค์ด ์๋ค. ๊ฐ ์ฒ ํ์์ ์ผ์ชฝ์ ์ ๊ฐ๋ฝ์ด ๋์ฌ ์์ผ๋ฉฐ ํ ์ด๋ธ์ ์ค์์ ํฐ ์์์ด ๋์ฌ ์๋ค. ๋ฐฐ๊ฐ ๊ณ ํ์ง๋ฉด ๊ทธ๋ค์ ์์ ์ ์์ชฝ์ ๋์ฌ ์๋ ์ ๊ฐ๋ฝ์ ์ก๊ณ ์คํ๊ฒํฐ๋ฅผ ๋จน๋๋ค.
์ ๊ฐ๋ฝ์ ๋์ง์ด ์์ด์ผ ๋น๋ก์ ๋จน์ ์ ์๋ค. ์ ์ฌ๋์ด ์ฌ์ฉํ๊ณ ์์ผ๋ฉด ๊ธฐ๋ค๋ ค์ผ ํ๋ค. ์คํ๊ฒํฐ๋ฅผ ๋จน์ ์ฒ ํ์๋ ๋ค์ ๋ฐฐ๊ฐ ๊ณ ํ์ง ๋๊น์ง ํฌํฌ๋ฅผ ๋๊ณ ์๋๋ค.
์ ์ํฉ์์ ์ฒ ํ์๋ฅผ ์ค๋ ๋๋ก, ํฌํฌ๋ฅผ ๊ณต์ ์์์ผ๋ก ์๊ฐํ๋ฉด ์ด๋ ์์์ ๋๊ณ ๊ฒฝ์ํ๋ ํ๋ก์ธ์ค์ ๋น์ทํ ์ํฉ์ด ๋๋ค. ๋ชจ๋๊ฐ ๋ฐฐ๊ฐ ๊ณ ํ ์ํ๊ฐ ๋์ด ์ผ์ชฝ์ ์๋ ์ ๊ฐ๋ฝ ๋ถํฐ ์ก์ ๊ฒฝ์ฐ, ๋ชจ๋๊ฐ ๋ฐฅ์ ๋ชป๋จน๊ณ ๊ตถ์ด์ฃฝ๋ ๊ธฐ์์ํ์ ๋น ์ง๋ค. ์ด๋ ๊ฒ ์ ์ค๊ณ๋์ง ์์ ์์คํ ์ deadlock, livelock, ์ฒ๋ฆฌ๋ ๋ฌธ์ , ํจ์จ์ฑ ์ ํ ๋ฌธ์ ์ ๋ง๋ฅ๋จ๋ฆฌ๊ธฐ ์ฝ๋ค.
๋น์ ์ด ๋ง๋ฅ๋จ๋ฆด ๋๋ถ๋ถ์ concurrent๊ด๋ จ ๋ฌธ์ ๋ค์ ์์ ์ธ ๊ฐ์ง ๋ฌธ์ ์ ๋ณํ์ผ ๊ฐ๋ฅ์ฑ์ด ๋๋ค. ์ด ์๊ณ ๋ฆฌ์ฆ๋ค์ ๊ณต๋ถํ๊ณ ์ค์ค๋ก ํด๋ฒ์ ์์ฑํจ์ผ๋ก์จ ์ด์ ๊ฐ์ ๋ฌธ์ ๋ค์ ์ง๋ฉดํ๋๋ผ๋ ์์ฐํ๊ฒ ๋์ฒํ ์ ์๋๋ก ํ์.
๋๊ธฐํํ๋ ๋ฉ์๋ ์ฌ์ด์ ์กด์ฌํ๋ ์์กด์ฑ์ ์ดํดํ๋ผ
๋๊ธฐํ๋ ๋ฉ์๋ ๊ฐ์ ์์กด์ฑ์ ๋์์ฑ ์ฝ๋์์ ์ฌ์ํ ๋ฒ๊ทธ๋ฅผ ์ผ์ผํฌ ์ ์๋ค. ์๋ฐ๋ synchronized
๋ผ๋ โ๋ฉ์๋ ํ๋๋ฅผ ๋ณดํธํ๋ ๋
ธํ
์ด์
โ์ ์ ๊ณตํ๋ค. ํ์ง๋ง ํ ํด๋์ค์ ๋ ๊ฐ ์ด์์ synchronized
๋ฉ์๋๊ฐ ์กด์ฌํ๋ฉด ๋ฌธ์ ๋ฅผ ์ผ์ผํฌ ์๋ ์๋ค. ์ฆ, synchronized
ํค์๋๊ฐ ๋ฌ๋ฆฐ ํจ์๋ฅผ ์์กด์ฑ์ด ์๊ฒ ์์ฐจ์ ์ผ๋ก ํธ์ถํ๊ฒ ๋๋ ๊ฒฝ์ฐ, ์์ ์ ์ํฅ์ ๋ฐ๊ธฐ ๋๋ฌธ์ ์ํ์ง ์๋ ๊ฒฐ๊ณผ๋ฅผ ๊ฐ์ ธ์ฌ ์ ์๋ค๋ ๋ง์ด๋ค.
/* Code 2-1: ๋ฌธ์ ๊ฐ ๋๋ ์ํฉ */
public class IntegerIterator implements Iterator<Integer> {
private Integer nextValue = 0;
public synchronized boolean hasNext() {
return nextValue < 100000;
}
public synchronized Integer next() {
if (nextValue == 100000)
throw new IteratorPastEndException();
return nextValue++;
}
public synchronized Integer getNextValue() {
return nextValue;
}
}
// Shared Resource
IntegerIterator iterator = new IntegerIterator();
// Threaded-Code
while(iterator.hasNext()) {
// nextValue๊ฐ 99999์ธ ์ํฉ์์ ๋ ์ค๋ ๋์์ ์์ฐจ์ ์ผ๋ก while(iterator.hasNext())๋ฅผ ํธ์ถํ๊ฒ ๋๋ฉด
// ๋ ์ค๋ ๋ ๋ชจ๋ while๋ฌธ ์์ผ๋ก ์ง์
ํ๊ฒ ๋๋ค. ์๋ํ๋ฉด ํด๋น ์กฐ๊ฑด๋ง ํ์ธํ๋ ๋ฉ์๋์๊ธฐ ๋๋ฌธ์ด๋ค.
// ์ด๋ ์์๋์ง ์์ ๊ฒฐ๊ณผ์ด๋ค.
// ์ด๋ฏธ 100000์ดํ์ธ ์ํฉ์ ๊ฐ์ ํ๊ณ ์๋ ๋์์ ํ๊ธธ ๋ฐ๋๋๋ฐ, ํต๊ณผํด๋ฒ๋ฆฐ ๊ฒ์ด๋ค.
int nextValue = iterator.next();
// do something with nextValue
}
์ด๋ฐ ์ํฉ์ด๋ฉด synchronized
ํค์๋๋ฅผ ์ฌ์ฉํ ์ด์ ๊ฐ ์๋ค. ์ด๋ฐ ๊ฒฝ์ฐ ๋ค์์ ์ธ๊ฐ์ง ๋ฐฉ๋ฒ์ผ๋ก ํด๊ฒฐํ์.
ํด๋ผ์ด์ธํธ ๊ธฐ๋ฐ ์ ๊ธ(Client-Based Locking)
๋จผ์ , ๊ณต์ ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ๋ ์ชฝ ์ฝ๋์์ ๊ณต์ ๊ฐ์ฒด๋ฅผ ์ ๊ทธ๋ ๋ฐฉ๋ฒ์ด ์๋ค.
/* Code 2-2: Client-Based Locking */
// Shared Resource
IntegerIterator iterator = new IntegerIterator();
// Threaded-Code
while (true) {
int nextValue;
synchronized (iterator) { โ
if (!iterator.hasNext())
break;
nextValue = iterator.next();
}
doSometingWith(nextValue);
}
์ฌ์ฉํ๋ ์ชฝ์์ synchronized
ํค์๋๋ฅผ ํตํด์ thread๊ฐ ์์ฐจ์ ์ผ๋ก ์ ๊ทผํ๊ณ , ๊ทธ ์์์ ์กฐ๊ฑด์ ํ์ํ๋๋ก ํ๋ค. ์ด๋ด ๊ฒฝ์ฐ, ์ํ๋ ๋ฐฉ์๋๋ก ์์ฐจ์ ์ผ๋ก ๋ค์ด์ค๋๋ก ๋ง๋ค ์ ์๋ค.
์ฌ์ค ์ด ๋ฐฉ์์ ์ข์ง ์๋ค. ํด๋น ์ฝ๋๋ฅผ ์ฌ์ฉํ๋ ๋ชจ๋ ํด๋ผ์ด์ธํธ์์ lock์ ํ์๋กํ๊ธฐ ๋๋ฌธ์, ๊ฒฝ๊ณ์์ญ์ด ํฉ์ด์ ธ ์ ์ง๋ณด์ ๋น์ฉ์ด ์์นํ๋ค.
์๋ฒ ๊ธฐ๋ฐ ์ ๊ธ(Server-Based Locking)
์ด๋ฒ์๋ ์ ๊ณตํ๋ ์ชฝ์์ lock์ ๊ฑฐ๋ ๋ฐฉ๋ฒ์ด๋ค.
/* Code 2-3: Server-Based Locking */
public class IntegerIteratorServerLocked {
private Integer nextValue = 0;
public synchronized Integer getNextOrNull() { โ
if (nextValue < 100000)
return nextValue++;
else
return null;
}
}
// Shared Resource
IntegerIterator iterator = new IntegerIterator();
// Threaded-Code
while (true) {
Integer nextValue = iterator.getNextOrNull();
if (next == null)
break;
// do something with nextValue
}
๋์์ ์ํํ๋ ์กฐ๊ฑด์ ํ์ํ๋ ํจ์๋ฅผ ๋ด๋ถ๋ก ๋ฃ์ด์ ํด๊ฒฐํ๋ค. ์ฌ์ค ๊ฐ์ฅ ์์์ ์ค๋ช ํ ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋ ์ฝ๋๋, ๋์์ ์งํ์ ํ๋จํ๋ ํจ์์ ๋์์ด ๋ถ๊ธฐ๋์ด ์๊ธฐ ๋๋ฌธ์ ๋ฐ์ํ๋ค.
์ด ๊ฒฝ์ฐ, ์๊ณ ์์ญ์ ์ต์ํํ๊ธฐ ๋๋ฌธ์ ํด๋ผ์ด์ธํธ ๊ธฐ๋ฐ ์ ๊ธ๋ณด๋ค ์ข์ ๋ฐฉ์์ด๋ค.
์ค๊ณ๋ ์๋ฒ(Adapted Server)
/* Code 2-4: Adapted Server */
public class ThreadSafeIntegerIterator {
private IntegerIterator iterator = new IntegerIterator();
public synchronized Integer getNextOrNull() { โ
if(iterator.hasNext())
return iterator.next();
return null;
}
}
// Shared Resource
IntegerIterator iterator = new IntegerIterator();
// Threaded-Code
while (true) {
Integer nextValue = iterator.getNextOrNull();
if (next == null)
break;
// do something with nextValue
}
์ด๋ฒ์๋ iterator
๋ฅผ ๋ด๋ถ์ ๊ฐ์ง์ผ๋ก์ ์๊ณ์์ญ์ ์ต์ํํ๋ฉด์ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ค. ๊ธฐ๋ณธ์ ์ธ ๋ฐฉ์์ ์๋ฒ ๊ธฐ๋ฐ ์ ๊ธ๊ณผ ๋์ผํ๋, ์๋ํํฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํด์ผ ํ๋ ๊ฒฝ์ฐ ์ฌ์ฉํ๋ฉด ์ข์ ๋ฐฉ์์ด๋ค.
๋๊ธฐํํ๋ ๋ถ๋ถ์ ์๊ฒ ๋ง๋ค์ด๋ผ
Synchronized
๋ก ์ํ๋๋ ์ ๊ธ์ ๋๋ ์ด์ ์ค๋ฒํค๋๋ฅผ ๋ง๋ค๊ธฐ ๋๋ฌธ์ ์ฐ์ฐ ๋น์ฉ์ด ๋น์ธ๋ค. ๊ทธ๋ ๊ธฐ ๋๋ฌธ์ ๊ฐ๋ฅํ ํ ์๊ฒ ๋ง๋ค์ด์ผ ํ๋ค.
์๊ฒ ๋ง๋ค๋ฉด์๋ critical section์ ๊ผญ ๋ณดํธ๋์ด์ผ ํ๋ค.
์ถ์ฒ: ๋๊ธฐํ๋ ์์ญ์ ์ต๋ํ ์๊ฒ ๋ง๋ค์ด๋ผ.
์ฌ๋ฐ๋ฅธ ์ข ๋ฃ ์ฝ๋๋ ๊ตฌํํ๊ธฐ ์ด๋ ต๋ค
๊ฐ๋ฐ ์ด๊ธฐ์ ์์คํ ์ข ๋ฃ์ ๋ํด ๊ณ ๋ฏผํ๊ณ ๊ตฌํํ๋ผ. ์ด ์์ ์ ์๊ฐ๋ณด๋ค ์ค๋ ๊ฑธ๋ฆด ๊ฒ์ด๋ค. ๊ธฐ์กด์ ๊ตฌํํ ์๊ณ ๋ฆฌ์ฆ์ ๋ฆฌ๋ทฐํ๋ ๊ฒ๋ ํ์ํ๋ค.
โํญ์ ์ด์ ์์ด์ผ ํ๋ ์ฝ๋โ์ ์์ฑ์ โ์ ์ ๋์ํ๊ณ ์กฐ์ฉํ ๋๋๋โ ์ฝ๋์ ์์ฑ๊ณผ๋ ๋ค๋ฅด๋ค. ๊น๋ํ๊ฒ ์ข ๋ฃํ๋ ๊ฒฝ์ฐ๋ ๊ตฌํํ๊ธฐ๊ฐ ์ด๋ ต๋ค. ํํ ๋ฐ์ํ๋ ๋ฌธ์ ๋ก๋ Dead Lock์ด ์๋ค. ๋ถ๋ชจ ์ค๋ ๋๊ฐ ์์ ์ค๋ ๋๋ฅผ ์ฌ๋ฌ๊ฐ๋ฅผ ๋ง๋ ํ ๋ชจ๋๊ฐ ๋๋๊ธฐ๋ฅผ ๊ธฐ๋ค๋ ธ๋ค ์์์ ํด์ ํ๊ณ ์ข ๋ฃํ๋ค๊ณ ํด๋ณด์. ์์ ์ค๋ ๋ ๊ฐ์ dead lock์ด ๊ฑธ๋ ธ๋ค๋ฉด ์ด๋จ๊น? ํน์ ์์ฐ์/์๋น์ ๊ด๊ณ๋ผ๋ฉด? ๋ ๊ฒฝ์ฐ ๋ชจ๋, ๋ฌดํ์ ๋๊ธฐํ๋ ์ํฉ์ด ๋ฐ์ํ ์ ์๋ค. ์ด๋ฐ ๊ฒฝ์ฐ ์ข ๋ฃ๋ ๋ถ๊ฐ๋ฅํด์ง๋ค. ๋ค์ค ์ค๋ ๋ ์ฝ๋๋ฅผ ์ง๋ ๊ฒฝ์ฐ, ์ฌ๋ฐ๋ฅด๊ฒ ๊ตฌํํ๋๋ฐ ์๊ฐ์ ํฌ์ํด์ผ ํ๋ค.
์ค๋ ๋ ์ฝ๋ ํ ์คํธํ๊ธฐ
๋ค์ค ์ค๋ ๋ ํ๊ฒฝ์์ ํ ์คํธ๋ฅผ ํ๋ค๋ฉด, ํ๋ก๊ทธ๋จ ์ค์ ๊ณผ ์์คํ ์ค์ ์ ๋ฐ๊ฟ๊ฐ๋ฉฐ ์์ฃผ ๋๋ฆฌ์. ๊ฐํ์ ์ผ๋ก ํต๊ณผํ๋ ํ ์คํธ ์ฝ๋๋ ๊ทธ๋ฅ ๋์ด๊ฐ์ ๋ ์ผ์ด ์๋๋ค.
๋จ์ผ ์ค๋ ๋ ํ๊ฒฝ์ด๋ผ๋ฉด, ํ ์คํธ ์ฝ๋๊ฐ ์ถฉ๋ถํ ์๋ฏธ๊ฐ ์๋ค. ์ ํ์ฑ์ ๋ณด์ฅํ๊ธฐ ๋๋ฌธ์ด๋ค. ํ์ง๋ง ๋ค์ค ์ค๋ ๋ ํ๊ฒฝ์ด๋ผ๋ฉด, ๊ณ ๋ คํ ์ํฉ์ด ๋งค์ฐ ๋ง์์ง๋ค.
๋ง์ด ์ ๋๋ ์คํจ๋ ์ ์ ์ ์ธ ์ค๋ ๋ ๋ฌธ์ ๋ก ์ทจ๊ธํ๋ผ
์์คํ ์คํจ๋ฅผ ์ผํ์ฑ์ด๋ผ ์น๋ถํ์ง ๋ง๋ผ.
๋ค์ค ์ค๋ ๋ ์ฝ๋๋ฅผ ์ง๋ค๋ณด๋ฉด โ๋ง์ด ์๋๋โ ์ค๋ฅ๋ฅผ ์ผ์ผํจ๋ค. ์ค์ ๋ก ๋ด ์์์ผ๋ก๋ ๋์๊ฐ์ผ ํ๋๋ฐ, ๊ทธ๋ ์ง ์์ ์ํฉ์ ๋ง์ฃผํ๋ค. ์ด๋ ๋ค์ค ์ค๋ ๋ ํ๊ฒฝ์ด ์ฃผ๋ ๋ณต์กํจ ๋๋ฌธ์ ๋ฐ์ํ๋ค. ์ง๊ด์ ์ผ๋ก ์ดํดํ๊ธฐ๊ฐ ์ด๋ ต๊ธฐ ๋๋ฌธ์ด๋ค. ๊ทธ๋ ๊ธฐ ๋๋ฌธ์ ์ฐ๋ฆฌ ๊ฐ๋ฐ์๋ค์, ์ด๋ฐ ๋ฌธ์ ๋ฅผ ์ฐ์ฃผ์ ๋ฌธ์ (?), ํ๋์จ์ด ๋ฌธ์ ๋ฑ ์ผํ์ฑ ๋ฌธ์ ๋ก ์น๋ถํ๊ณ ๋ฌด์ํ๊ธฐ ๋ง๋ จ์ด๋ค. ํ์ง๋ง ์ด๋ ๊ฒ ์ผํ์ฑ ๋ฌธ์ ๋ก ์น์๋ ๋ฌธ์ ๋ฅผ ๊ณ์ ๋ฌด์ํ๋ค๋ฉด ์๋ชป๋ ์ฝ๋ ์์ ์ฝ๋๊ฐ ๊ณ์ ์์ธ๋ค.
๋ค์ค ์ค๋ ๋๋ฅผ ๊ณ ๋ คํ์ง ์์ ์์ฐจ ์ฝ๋๋ถํฐ ์ ๋๋ก ๋๊ฒ ๋ง๋ค์
์ค๋ ๋ ํ๊ฒฝ ๋ฐ์์ ์๊ธฐ๋ ๋ฒ๊ทธ์ ์ค๋ ๋ ํ๊ฒฝ์์ ์๊ธฐ๋ ๋ฒ๊ทธ๋ฅผ ๋์์ ๋๋ฒ๊น ํ์ง ๋ง๋ผ. ์ค๋ ๋ ํ๊ฒฝ ๋ฐ์์ ์ฝ๋๋ฅผ ๋จผ์ ํ์ธํ๊ณ ์ค๋ ๋ ํ๊ฒฝ์ ์ฒดํฌํ์.
์ค๋ ๋ ๋ด๋ถ์์ ํน์ ์ฝ๋๊ฐ ๋์๊ฐ๊ณ ์๋ค๋ฉด, ๋ด๋ถ์์ ๋์๊ฐ๋ ์ฝ๋์ ํ ์คํธ๋ถํฐ ์ํํ์. ๋ด๋ถ์ ๋ค์ด๊ฐ๋ ์ฝ๋๋ ์ค๋ ๋์ ๊ด๋ จ์ด ์๊ธฐ ๋๋ฌธ์, ์ ํ์ฑ ์ฒดํฌ๊ฐ ๊ฐ๋ฅํ๋ค.
๋ค์ค ์ค๋ ๋๋ฅผ ์ฐ๋ ์ฝ๋ ๋ถ๋ถ์ ๋ค์ํ ํ๊ฒฝ์ ์ฝ๊ฒ ๋ผ์ ๋ฃ์ ์ ์๊ฒ ์ค๋ ๋ ์ฝ๋๋ฅผ ๊ตฌํํ๋ผ
๋ค์ํ ์ค์ ์์ ์คํํ ๋ชฉ์ ์ผ๋ก ๋ค๋ฅธ ํ๊ฒฝ์ ์ฝ๊ฒ ๋ผ์ ๋ฃ์ ์ ์๊ฒ ์ฝ๋๋ฅผ ๊ตฌํํ์.
- ํ๋์ ์ค๋ ๋ ํ๊ฒฝ, ์ฌ๋ฌ ์ค๋ ๋ ํ๊ฒฝ, ์คํ ์ค ์ค๋ ๋ ์๋ฅผ ๋ณ๊ฒฝํ์ฌ ํ ์คํธ ํ๋ค.
- ์ค๋ ๋ ์ฝ๋๋ฅผ ์ค์ ํ๊ฒฝ, ํ ์คํธ ํ๊ฒฝ์์ ๋๋ ค๋ณธ๋ค.
- ์ฌ๋ฌ ์๋(๋น ๋ฅด๊ฒ, ์ฒ์ฒํ)๋ก ํ ์คํธ ์ฝ๋๋ฅผ ๋๋ ค๋ณธ๋ค.
- ๋ฐ๋ณต ํ ์คํธ๊ฐ ๊ฐ๋ฅํ๋๋ก ํ ์คํธ ์ผ์ด์ค๋ฅผ ์์ฑํ๋ค.
๋ค์ค ์ค๋ ๋๋ฅผ ์ฐ๋ ์ฝ๋ ๋ถ๋ถ์ ์ํฉ์ ๋ง๊ฒ ์กฐ์จํ ์ ์๊ฒ ์์ฑํ๋ผ
์ ์ ํ ์ค๋ ๋ ๊ฐ์๋ฅผ ํ์ ํ๋ ค๋ฉด ์๋นํ ์ํ์ฐฉ์ค๊ฐ ํ์ํ๋ค. ๊ทธ๋ ๊ธฐ ๋๋ฌธ์, ์ฒ์๋ถํฐ ๋ค์ํ ์ค์ ์ผ๋ก ํ๋ก๊ทธ๋จ์ ์ฑ๋ฅ ์ธก์ ๋ฐฉ๋ฒ์ ์๊ฐํ์. ์ฆ, ์ค๋ ๋ ๊ฐ์๋ฅผ ์กฐ์จํ๊ธฐ ์ฝ๊ฒ ์ฝ๋๋ฅผ ๊ตฌํํ์. ํ๋ก๊ทธ๋จ์ด ๋์ํ๋ ์์ ์ ์ค๋ ๋ ๊ฐ์๋ฅผ ๋ณ๊ฒฝํ๋ ๋ฐฉ๋ฒ๋ ๊ณ ๋ คํ์. ํน์ ์ฒ๋ฆฌ์จ๊ณผ ํจ์จ์ ๋ฐ๋ผ ์ค๋ ๋ ๊ฐ์๋ฅผ ์กฐ์จํ๋ ์ฝ๋๋ฅผ ์๊ฐํด๋ณด์.
ํ๋ก์ธ์ ์๋ณด๋ค ๋ง์ ์ค๋ ๋๋ฅผ ๋๋ ค๋ณด๋ผ
์์คํ ์์ ์ด์ํ๋ ๋ฌผ๋ฆฌ ์ค๋ ๋ ๊ฐ์์ ์ํํธ์จ์ด ์ค๋ ๋ ๊ฐ์๊ฐ ๋ค๋ฅด๋ฉด ์ค์ํ์ด ์ผ์ด๋๋ค. ์ค์ํ์ด ์ฆ์ผ๋ฉด ์๊ณ์์ญ์ ๋นผ๋จน์ ์ฝ๋, Dead Lock์ ๋ฐ๊ฒฌํ๊ธฐ ์ฌ์์ง๋ค. ์์๋ก ์ํํธ์จ์ด ์ค๋ ๋๋ฅผ ๋ง์ด ๋ง๋ค์ด ์ค์ํ์ ์ผ์ผ์ผ ๋ฌธ์ ๋ฅผ ํ์ธํด๋ณด์.
๋ค๋ฅธ ํ๋ซํผ์์ ๋๋ ค๋ณด๋ผ
์ฒ์๋ถํฐ, ๊ทธ๋ฆฌ๊ณ ์์ฃผ ๋ชจ๋ Target Platform์์ ์ฝ๋๋ฅผ ๋๋ ค๋ณด์.
์ ์๋ ์๋์ฐ XP, OS X์์ ์์ ์ฝ๋๋ฅผ ๋๋ฆด ์ผ์ด ์๊ฒผ๋๋ฐ, ์ด๋๋ ๋๊ณ ์ด๋๋ ์๋๋ค. ๊ทธ ์ด์ ๋ ๊ฐ๊ฐ์ ์ด์์ฒด์ ๋ง๋ค ์ค๋ ๋๋ฅผ ์ฒ๋ฆฌํ๋ ์ ์ฑ ์ด ๋ฌ๋๊ธฐ ๋๋ฌธ์ด๋ค. ์ด๋ฐ ๋ฌธ์ ๊น์ง ๋ด์ํ๊ธฐ ์ํด์๋ ์ฌ๋ฌ ํ๋ซํผ์์ ํ ์คํธ๋ฅผ ์ํํ๋ ๊ฒ์ด ์ข๋ค.
์ฝ๋์ ๋ณด์กฐ ์ฝ๋ instrument๋ฅผ ๋ฃ์ด ๋๋ ค๋ผ. ๊ฐ์ ๋ก ์คํจ๋ฅผ ์ผ์ผํค๊ฒ ํด๋ณด๋ผ
์ค๋ ๋ ๋ฒ๊ทธ๊ฐ ์ฐ๋ฐ์ ์ด๊ณ , ์ฐ๋ฐ์ ์ด๋ฉฐ, ์ฌํ์ด ์ด๋ ค์ด ์ด์ ๋ ์ฝ๋๊ฐ ์คํ๋๋ ์์ฒ๊ฐ์ง ๊ฒฝ๋ก์ค์ ์์ฃผ ์์๋ง ์คํจํ๊ธฐ ๋๋ฌธ์ด๋ค.
์ด๋ ๊ฒ ๋น๋ ํ์๊ฐ ๊ทน๋๋ก ์ ์ ๊ฒฝ์ฐ์ ์๋ฌ๋ฅผ ์ก๊ธฐ ์ํด์๋ ์ด๋ป๊ฒ ํด์ผํ ๊น? ์ด๊ฑด ๋น๋จ ๋ค์ค ์ค๋ ๋ ํ๊ฒฝ์์๋ง ๋ฐ์ํ๋ ํด๊ฒฐ์ฑ ์ ์๋๋ค. ๊ฐ์ฅ ๋จผ์ ํด๋ณผ ๋ฐฉ๋ฒ์ ๋น๋์๋ฅผ ๊ทน๋๋ก ์ฌ๋ ค ๋ฐ์ ํ์๋ฅผ ๋๋ฆฌ๋ ๊ฒ์ด๋ค. ํ๋ฅ ์ ์ผ๋ก ๋ฐ์ ์๋ ๊ฐ์ผ๋, ํ์๊ฐ ๋์ด๋๊ธฐ ๋๋ฌธ์ ์๋์ ์ผ๋ก ๋ฐ์ํ๋ ์ํฉ์ ๋ ์์ฃผ ๋ง์ฃผํ ์ ์๋ค.
๋ค์์ผ๋ก๋ ๋ณด์กฐ ์ฝ๋๋ฅผ ์ถ๊ฐํ์ฌ ์คํ๋๋ ์์๋ฅผ ๋ฐ๊ฟ์ฃผ๋ ๊ฒ์ด๋ค. wait()
, sleep()
, yield()
, priority()
๋ฑ๊ณผ ๊ฐ์ ๋ฉ์๋๋ฅผ ์ถ๊ฐํ์ฌ ๋ค์ํ ์์๋ก ์คํ๋๋๋ก ํด๋ณด์.
์ง์ ๊ตฌํํ๊ธฐ
์ด๋ wait()
, sleep()
, yield()
, priority()
๋ฑ์ ๋ฉ์๋๋ฅผ ์ฌ์ฉํด ์คํ ๊ฒฝ๋ก๋ฅผ ๋ณ๊ฒฝํจ์ผ๋ก์จ ์ฝ๋์ ๋ฌธ์ ๋ฅผ ๋ฐ๊ฒฌํ๋ ๋ฐฉ๋ฒ์ด๋ค.
/* Code 3-1 */
public synchronized String nextUrlOrNull() {
if(hasNext()) {
String url = urlGenerator.next();
Thread.yield(); โ
// inserted for testing.
updateHasNext();
return url;
}
return null;
}
yield()
๋ฉ์๋๋ฅผ ํธ์ถํจ์ผ๋ก์จ ์ฝ๋์ ์คํ ๊ฒฝ๋ก๋ฅผ ๋ณ๊ฒฝํ ์ ์๋ค. ๋ง์ฝ ์ ์ฝ๋์์ ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋ค๋ฉด ์ด๋ yield()
๋ฅผ ์ถ๊ฐํด ์๊ธด ๋ฌธ์ ๊ฐ ์๋๋ผ ์ด๋ฏธ ์กด์ฌํ๋ ๋ฌธ์ ๋ฅผ ๋ช
๋ฐฑํ ๋ง๋ ๊ฒ ๋ฟ์ด๋ค. ํ์ง๋ง ์ด ๋ฐฉ๋ฒ์๋ ๋ช ๊ฐ์ง ๋ฌธ์ ๊ฐ ์๋ค.
- ํ ์คํธํ ๋ถ๋ถ์ ์ง์ ์ฐพ์์ผ ํ๋ค.
- ์ด๋์ ์ด๋ ๋ฉ์๋๋ฅผ ํธ์ถํด์ผ ํ ์ง ์๊ธฐ ์ด๋ ต๋ค.
- ์ด์ ๊ฐ์ ์ฝ๋๋ฅผ ์ ํ์ ํฌํจํด ๋ฐฐํฌํ๋ ๊ฒ์ ๋ถํ์ํ๊ฒ ํผํฌ๋จผ์ค๋ฅผ ์ ํ์ํฌ ๋ฟ์ด๋ค.
- ๋ฌด์์์ ์ด๋ค. ์ค๋ฅ๊ฐ ๋๋ฌ๋ ์๋ ์๊ณ , ์๋ ์๋ ์๋ค. ์๋ ํ๋ฅ ์ด ๋ ๋๋ค.
์ด๋ฐ ๊ฒฝ์ฐ, debug ํค์๋๋ฅผ ํตํด debug์์๋ง ์ปดํ์ผ ๋๋๋ก ํ๋ ๋ฐฉ๋ฒ์ ์ฌ์ฉํ ์ ์๊ฒ ๋ค. ๊ทผ๋ณธ์ ์ผ๋ก๋ POJO ๋จ์๋ก ๋๋ ์, instrument code๋ฅผ ์ฝ์ ํ ๋ถ๋ถ์ ์ฐพ๊ธฐ ์ฝ๊ธฐํ๋ ๋ฐฉ๋ฒ์ด ์๊ฒ ๋ค.
์๋ํ
์์ ๋ค๋ฅด๊ฒ Aspect-oriented Framework, CGLib, ASM๋ฑ์ ํตํด ํ๋ก๊ทธ๋จ์ ์ผ๋ก ์ฝ๋๋ฅผ ์กฐ์ํ ์๋ ์๋ค.
/* Code 4-1 */
public class ThreadJigglePoint {
public static void jiggle() { }
}
public synchronized String nextUrlOrNull() {
if(hasNext()) {
ThreadJiglePoint.jiggle(); โ
String url = urlGenerator.next();
ThreadJiglePoint.jiggle(); โ
updateHasNext();
ThreadJiglePoint.jiggle(); โ
return url;
}
return null;
}
jiggle์ ์์ด๋ก ํ๋ค๋ค๋ผ๋ ๋ป์ด๋ค. ์ฆ, ํด๋น ๋ฉ์๋๋ฅผ ๋ง๋ค์ด๋๊ณ , ๋๋ฒ๊ทธ ํ๊ฒฝ์์ ๋ด๋ถ์ ์ผ๋ก thread๋ฅผ sleep()
ํ๊ฑฐ๋, yield()
ํ๋ ๋์์ ๋ฃ์ด๋ฒ๋ฆฌ๋ ๊ฒ์ด๋ค. ํน์ ๋ฌด์์๋ก ๋ ์ค ํ๋์ ๋ฉ์๋๊ฐ ์คํ๋๋๋ก ํ ์ ์๊ฒ ๋ค. ๋ฐฐํฌ ํ๊ฒฝ์์๋ ๊ตฌํ์ ๋นผ๋ฒ๋ฆฐ๋ค.
๊ฒฐ๋ก
- ๋์์ฑ ์ฝ๋๋ ์ ๋๋ก ์์ฑํ๊ธฐ ์ด๋ ต๋ค.
- SRP๋ฅผ ์ค์ํด์ผ ํ๋ค. ์ค๋ ๋๋ฅผ ๊ด๋ฆฌํ๋ ์ฝ๋์ ๊ทธ์ ๋ฌด๊ดํ ์ฝ๋๋ ๊ตฌ๋ถํด์ผ ํ๋ค.
- ํ ์คํธ์์๋ ์ค๋ ๋ ๋ฌด๊ดํ ์ฝ๋๋ถํฐ ๋์์ ์ ํ์ฑ์ ๊ฒ์ฆํ๋ค.
- ๋์์ฑ ์ค๋ฅ๊ฐ ๋ฐ์ํ๋ ์ ์ ์ ์ธ ์์ธ์ ๋ํด ๋จผ์ ์์งํ๋ค. ์ด๋ฅผ ์ํ ๊ธฐ๋ณธ ์๊ณ ๋ฆฌ์ฆ์ ์ดํดํ๋ค.
- ์๊ณ ์์ญ์ ์ฐพ๋ ๋ฐฉ๋ฒ, ๊ทธ๋ฆฌ๊ณ ํน์ ์ฝ๋์ ์ง์ ์ ์ ๊ทธ๋ ๋ฐฉ๋ฒ์ ์ดํดํ๋ค.
- ์ ์ง๋ณด์๋ฅผ ์ํด ์๊ณ ์์ญ์ ์ต๋ํ ์ค์ธ๋ค.
- ํด๋ผ์ด์ธํธ์๊ฒ ๊ณต์ ์ํ๋ฅผ ๊ด๋ฆฌํ๋ ์ฑ ์์ ๋ ๋๊ธฐ์ง ์๋๋ค.
- ๋ค์ค ์ค๋ ๋ ํ๊ฒฝ์์ ๋ฐ์ํ๋ ํ ์คํธ ์คํจ๋ฅผ ์ผํ์ฑ์ผ๋ก ๋๊ธฐ์ง ๋ง์๋ผ.
- ๋ค์ํ ํ๊ฒฝ, ์ค๋ ๋ ์, ์คํ ์๋, ๋ณด์กฐ ์ฝ๋, ๋น๋์ ์ฆ๋ ๋ฑ์ ๋ฐฉ๋ฒ์ ํตํด ์ฝ์ฌ๋ฆฌ ๋ฐ์ํ์ง ์๋ ๋์์ฑ ๋ฌธ์ ์ ๋น๋์๋ฅผ ๋ํ ๋ฌธ์ ๋ฅผ ์ฐพ์๋ผ.