์๊ฐ
๋ฐ๋ผ์ ์ฐ๋ฆฌ๋ Java์ ์ค๋ ๋๊ฐ ์๋ค๋ ๊ฒ์ ์๊ณ ์์ต๋๋ค. Better Together: Java and the Thread class ๋ผ๋ ์ ๋ชฉ์ ๋ฆฌ๋ทฐ์์ ์ด์ ๋ํด ์ฝ์ ์ ์์ต๋๋ค . ํํธ I โ ์คํ ์ค๋ ๋ . ์์ ์ ๋ณ๋ ฌ๋ก ์ํํ๋ ค๋ฉด ์ค๋ ๋๊ฐ ํ์ํฉ๋๋ค. ์ด๋ก ์ธํด ์ค๋ ๋๊ฐ ์ด๋ป๊ฒ๋ ์๋ก ์ํธ ์์ฉํ ๊ฐ๋ฅ์ฑ์ด ๋์ต๋๋ค. ์ด๊ฒ์ด ์ด๋ป๊ฒ ๋ฐ์ํ๊ณ ์ด๋ค ๊ธฐ๋ณธ ๋๊ตฌ๊ฐ ์๋์ง ์ดํด๋ณด๊ฒ ์ต๋๋ค.
์์ฐํ๋ค
Thread.yield() ๋ ๋นํน์ค๋ฝ๊ณ ๊ฑฐ์ ์ฌ์ฉ๋์ง ์์ต๋๋ค. ์ธํฐ๋ท์์ ๋ค์ํ ๋ฐฉ์์ผ๋ก ์ค๋ช ๋ฉ๋๋ค. ์ค๋ ๋ ์ฐ์ ์์์ ๋ฐ๋ผ ์ค๋ ๋๊ฐ ๋ด๋ ค๊ฐ ์ค๋ ๋ ๋๊ธฐ์ด์ด ์๋ค๊ณ ์ฐ๋ ์ผ๋ถ ์ฌ๋๋ค์ ํฌํจํฉ๋๋ค. ๋ค๋ฅธ ์ฌ๋๋ค์ ์ค๋ ๋๊ฐ "์คํ ์ค"์์ "์คํ ๊ฐ๋ฅ"์ผ๋ก ์ํ๋ฅผ ๋ณ๊ฒฝํ ๊ฒ์ด๋ผ๊ณ ๊ธฐ๋กํฉ๋๋ค(์ด๋ฌํ ์ํ ๊ฐ์ ๊ตฌ๋ถ์ด ์์์๋ ๋ถ๊ตฌํ๊ณ , ์ฆ Java๋ ์ด๋ฅผ ๊ตฌ๋ถํ์ง ์์ต๋๋ค). ํ์ค์ ํจ์ฌ ๋ ์๋ ค์ ธ ์์ง๋ง ์ด๋ค ์๋ฏธ์์๋ ๋ ๋จ์ํ๋ค๋ ๊ฒ์ ๋๋ค. ๋ฉ์๋ ์ค๋ช ์ ์
yield()
์ฝ์ด๋ณด๋ฉด ๋ถ๋ช
ํ๋ค.yield()
๋ฉ์๋๋ ์ค์ ๋ก Java ์ค๋ ๋ ์ค์ผ์ค๋ฌ์ ์ด ์ค๋ ๋์ ๋ ์ ์ ์คํ ์๊ฐ์ด ์ฃผ์ด์ง ์ ์๋ค๋ ๋ช ๊ฐ์ง ๊ถ์ฅ ์ฌํญ๋ง ์ ๊ณตํฉ๋๋ค. ๊ทธ๋ฌ๋ ์ค์ ๋ก ๋ฐ์ํ๋ ๊ฒ, ์ฆ ์ค์ผ์ค๋ฌ๊ฐ ๊ถ์ฅ ์ฌํญ์ ๋ฐ๋ผ ์๋ํ๋์ง ์ฌ๋ถ์ ์ผ๋ฐ์ ์ผ๋ก ์ํํ๋ ์์
์ JVM์ ๊ตฌํ ๋ฐ ์ด์ ์ฒด์ ์ ๋ฐ๋ผ ๋ค๋ฆ
๋๋ค. ๊ทธ๋ฆฌ๊ณ ๊ทธ๊ฒ์ ๋ค๋ฅธ ์์ธ๋ค์ ๋ฐ๋ผ์๋ ๋ฌ๋ผ์ง ์ ์์ต๋๋ค. ๋ชจ๋ ํผ๋์ Java ์ธ์ด๊ฐ ๋ฐ์ ํจ์ ๋ฐ๋ผ ๋ฉํฐ์ค๋ ๋ฉ์ด ๋ค์ ์๊ฐ๋์๊ธฐ ๋๋ฌธ์ผ ๊ฐ๋ฅ์ฑ์ด ํฝ๋๋ค. ์์ธํ ๋ด์ฉ์ Java Thread.yield() ์๊ฐ: ๊ฐ์๋ฅผ ์ฐธ์กฐ ํ์ญ์์ค .
์
์ค๋ ๋๋ ์คํ ์ค์ ํด๋ฉด ์ํ๊ฐ ๋ ์ ์์ต๋๋ค. ์ด๊ฒ์ ๋ค๋ฅธ ์ค๋ ๋์ ์ํธ ์์ฉํ๋ ๊ฐ์ฅ ์ฌ์ด ์ ํ์ ๋๋ค. Java ์ฝ๋๋ฅผ ์คํํ๋ Java ๊ฐ์ ๋จธ์ ์ ์คํํ๋ ์ด์ ์ฒด์ ์๋ ์์ฒด ์ค๋ ๋ ์ค์ผ์ค๋ฌ๊ฐ ์์ต๋๋ค . ์์ํ ์ค๋ ๋์ ์๊ธฐ๋ฅผ ๊ฒฐ์ ํฉ๋๋ค. ํ๋ก๊ทธ๋๋จธ๋ JVM์ ํตํด์๋ง Java ์ฝ๋์์ ์ง์ ์ด ์ค์ผ์ค๋ฌ์ ์ํธ ์์ฉํ ์ ์์ต๋๋ค. ๊ทธ ๋๋ ๊ทธ๋ ๋ ์ค์ผ์ค๋ฌ์๊ฒ ์ ์ ๋์ ์ค๋ ๋๋ฅผ ์ผ์ ์ค์งํ๋๋ก ์์ฒญํ ์ ์์ต๋๋ค. ์์ธํ ๋ด์ฉ์ Thread.sleep() ๋ฐ ๋ฉํฐ์ค๋ ๋ฉ ์๋ ๋ฐฉ์ ๋ฌธ์์์ ํ์ธํ ์ ์์ต๋๋ค . Windows ์ด์ ์ฒด์ ์์ ์ค๋ ๋๊ฐ ์๋ํ๋ ๋ฐฉ์์ ํ์ธํ ์๋ ์์ต๋๋ค. Internals of Windows Thread . ๊ทธ๋ฆฌ๊ณ ์ด์ ์ง์ ๋์ผ๋ก ํ์ธํด๋ณด์. ๋ค์ ์ฝ๋๋ฅผ ๋ค์ ์ด๋ฆ์ ํ์ผ์ ์ ์ฅํฉ๋๋คHelloWorldApp.java
.
class HelloWorldApp {
public static void main(String []args) {
Runnable task = () -> {
try {
int secToWait = 1000 * 60;
Thread.currentThread().sleep(secToWait);
System.out.println("Woke up");
} catch (InterruptedException e) {
e.printStackTrace();
}
};
Thread thread = new Thread(task);
thread.start();
}
}
๋ณด์๋ค์ํผ ํ๋ก๊ทธ๋จ์ด ์ข
๋ฃ๋ ํ 60์ด ๋์ ๋๊ธฐํ๋ ์์
์ด ์์ต๋๋ค. " " ๋ช
๋ น์ ์ฌ์ฉํ์ฌ ์ปดํ์ผํ javac HelloWorldApp.java
๋ค์ " java HelloWorldApp
"์ ์ฌ์ฉํ์ฌ ํ๋ก๊ทธ๋จ์ ์คํํฉ๋๋ค. ๋ณ๋์ ์ฐฝ์์ ํ๋ก๊ทธ๋จ์ ์์ํ๋ ๊ฒ์ด ๊ฐ์ฅ ์ข์ต๋๋ค. ์๋ฅผ ๋ค์ด, Windows์์๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค. start java HelloWorldApp
. ์ฐ๋ฆฌ๋ jps ๋ช
๋ น์ ์ฌ์ฉํ์ฌ PID(ํ๋ก์ธ์ค ID)๋ฅผ ๊ฐ์ ธ์ค๊ณ "๋ก ์ค๋ ๋ ๋ชฉ๋ก์ ์ฝ๋๋ค jvisualvm --openpid pid
. 
try {
TimeUnit.SECONDS.sleep(60);
System.out.println("Woke up");
} catch (InterruptedException e) {
e.printStackTrace();
}
์ฐ๋ฆฌ๊ฐ ๋ชจ๋ ๊ณณ์์ ์ฒ๋ฆฌํ๊ณ ์๋ค๋ ๊ฒ์ ์๊ณ ๊ณ์
จ์ต๋๊น InterruptedException
? ์ด์ ๋ฅผ ์ดํดํฉ์๋ค.
์ค๋ ๋.์ธํฐ๋ฝํธ()
๋ฌธ์ ๋ ์ค๋ ๋๊ฐ ๋๊ธฐ/์๋ฉด ์ค์ธ ๋์ ๋๊ตฐ๊ฐ ์ธํฐ๋ฝํธ๋ฅผ ์ํ ์ ์๋ค๋ ๊ฒ์ ๋๋ค. ์ด ๊ฒฝ์ฐInterruptedException
. ์ด ๋ฉ์ปค๋์ฆ์ ๋ฉ์๋๊ฐ ๋ ์ด์ ์ฌ์ฉ๋์ง ์์, ์ฆ ๊ตฌ์์ด๊ณ ๋ฐ๋์งํ์ง ์์ ๊ฒ์ผ๋ก ์ ์ธ๋ ํ์ ๋ง๋ค์ด์ก์ต๋๋ค Thread.stop()
. ๊ทธ ์ด์ ๋ stop()
๋ฉ์๋๊ฐ ํธ์ถ๋ ๋ ์ค๋ ๋๊ฐ ๋จ์ํ "์ข
๋ฃ"๋์ด ๋งค์ฐ ์์ธกํ ์ ์์๊ธฐ ๋๋ฌธ์
๋๋ค. ์ค๋ ๋๊ฐ ์ธ์ ์ค์ง๋ ์ง ์ ์ ์๊ณ ๋ฐ์ดํฐ ์ผ๊ด์ฑ์ ๋ณด์ฅํ ์ ์์ต๋๋ค. ์ค๋ ๋๊ฐ ์ข
๋ฃ๋๋ ๋์ ํ์ผ์ ๋ฐ์ดํฐ๋ฅผ ์ฐ๊ณ ์๋ค๊ณ ์์ํด ๋ณด์ญ์์ค. ์ค๋ ๋๋ฅผ ์ฃฝ์ด๋ ๊ฒ๋ณด๋ค Java์ ์ ์์๋ ์ค๋จ๋์ด์ผ ํ๋ค๊ณ ๋งํ๋ ๊ฒ์ด ๋ ๋
ผ๋ฆฌ์ ์ด๋ผ๊ณ ๊ฒฐ์ ํ์ต๋๋ค. ์ด ์ ๋ณด์ ์ด๋ป๊ฒ ๋์ํ๋๋๋ ์ค๋ ๋ ์์ฒด๊ฐ ๊ฒฐ์ ํ ๋ฌธ์ ๋ค. ์์ธํ ๋ด์ฉ์ Thread.stop์ด ๋ ์ด์ ์ฌ์ฉ๋์ง ์๋ ์ด์ ๋ฅผ ์ฝ์ด๋ณด์ธ์.์ค๋ผํด ์น์ฌ์ดํธ์์. ์๋ฅผ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
public static void main(String []args) {
Runnable task = () -> {
try {
TimeUnit.SECONDS.sleep(60);
} catch (InterruptedException e) {
System.out.println("Interrupted");
}
};
Thread thread = new Thread(task);
thread.start();
thread.interrupt();
}
์ด ์์์๋ 60์ด๋ฅผ ๊ธฐ๋ค๋ฆฌ์ง ์์ต๋๋ค. ๋์ "Interrupted"๋ฅผ ์ฆ์ ํ์ํฉ๋๋ค. interrupt()
์ค๋ ๋์์ ๋ฉ์๋๋ฅผ ํธ์ถํ๊ธฐ ๋๋ฌธ์
๋๋ค . ์ด ๋ฉ์๋๋ "์ธํฐ๋ฝํธ ์ํ"๋ผ๋ ๋ด๋ถ ํ๋๊ทธ๋ฅผ ์ค์ ํฉ๋๋ค. ์ฆ, ๊ฐ ์ค๋ ๋์๋ ์ง์ ์ก์ธ์คํ ์ ์๋ ๋ด๋ถ ํ๋๊ทธ๊ฐ ์์ต๋๋ค. ๊ทธ๋ฌ๋ ์ฐ๋ฆฌ๋ ์ด ํ๋๊ทธ์ ์ํธ์์ฉํ๊ธฐ ์ํ ๊ธฐ๋ณธ ๋ฐฉ๋ฒ์ ๊ฐ์ง๊ณ ์์ต๋๋ค. ๊ทธ๋ฌ๋ ๊ทธ๊ฒ์ด ์ ์ผํ ๋ฐฉ๋ฒ์ ์๋๋๋ค. ์ค๋ ๋๋ ๋ฌด์ธ๊ฐ๋ฅผ ๊ธฐ๋ค๋ฆฌ์ง ์๊ณ ๋จ์ํ ์์
์ ์ํํ๋ฉด์ ์คํ ์ค์ผ ์ ์์ต๋๋ค. ๊ทธ๋ฌ๋ ๋ค๋ฅธ ์ฌ๋๋ค์ด ํน์ ์๊ฐ์ ์์
์ ๋๋ด๊ธฐ๋ฅผ ์ํ ๊ฒ์ด๋ผ๊ณ ์์ํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด:
public static void main(String []args) {
Runnable task = () -> {
while(!Thread.currentThread().isInterrupted()) {
// Do some work
}
System.out.println("Finished");
};
Thread thread = new Thread(task);
thread.start();
thread.interrupt();
}
์์ ์์์ while
๋ฃจํ๋ ์ค๋ ๋๊ฐ ์ธ๋ถ์์ ์ค๋จ๋ ๋๊น์ง ์คํ๋ฉ๋๋ค. ํ๋๊ทธ ์ ๊ดํด์๋ isInterrupted
์ฐ๋ฆฌ๊ฐ ๋ฅผ ์ก์ผ๋ฉด InterruptedException
isInterrupted ํ๋๊ทธ๊ฐ ์ฌ์ค์ ๋๊ณ isInterrupted()
false๋ฅผ ๋ฐํํ๋ค๋ ๊ฒ์ ์๋ ๊ฒ์ด ์ค์ํฉ๋๋ค. Thread ํด๋์ค ์๋ ํ์ฌ ์ค๋ ๋์๋ง ์ ์ฉ๋๋ ์ ์ Thread.interrupted() ๋ฉ์๋๋ ์์ง๋ง ์ด ๋ฉ์๋๋ ํ๋๊ทธ๋ฅผ false๋ก ์ฌ์ค์ ํฉ๋๋ค! ์ค๋ ๋ ์ค๋จ ์ด๋ผ๋ ์ ๋ชฉ์ ์ด ์ฅ์์ ์์ธํ ๋ด์ฉ์ ์ฝ์ผ์ญ์์ค .
์กฐ์ธ(๋ค๋ฅธ ์ค๋ ๋๊ฐ ์๋ฃ๋ ๋๊น์ง ๋๊ธฐ)
๊ฐ์ฅ ๊ฐ๋จํ ์ ํ์ ๋๊ธฐ๋ ๋ค๋ฅธ ์ค๋ ๋๊ฐ ์๋ฃ๋๊ธฐ๋ฅผ ๊ธฐ๋ค๋ฆฌ๋ ๊ฒ์ ๋๋ค.
public static void main(String []args) throws InterruptedException {
Runnable task = () -> {
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
System.out.println("Interrupted");
}
};
Thread thread = new Thread(task);
thread.start();
thread.join();
System.out.println("Finished");
}
์ด ์์์ ์ ์ค๋ ๋๋ 5์ด ๋์ ํด๋ฉด ์ํ๊ฐ ๋ฉ๋๋ค. ๋์์ ์ฃผ ์ค๋ ๋๋ ์ ์๋ ์ค๋ ๋๊ฐ ๊นจ์ด๋ ์์
์ ๋ง์น ๋๊น์ง ๊ธฐ๋ค๋ฆฝ๋๋ค. JVisualVM์์ ์ค๋ ๋์ ์ํ๋ฅผ ๋ณด๋ฉด ๋ค์๊ณผ ๊ฐ์ด ํ์๋ฉ๋๋ค. 
join
์คํ๋๋ Java ์ฝ๋๊ฐ ์๋ ๋ฉ์๋์ด๊ธฐ ๋๋ฌธ์ ๋งค์ฐ ๊ฐ๋จํฉ๋๋ค . wait()
์ค๋ ๋๊ฐ ์ฃฝ์๋ง์(์์
์ด ๋๋๋ฉด) ๋๊ธฐ๊ฐ ์ค๋จ๋ฉ๋๋ค. ๊ทธ๋ฆฌ๊ณ ๊ทธ๊ฒ์ด ๋ฐฉ๋ฒ์ ๋ชจ๋ ๋ง๋ฒ์
๋๋ค join()
. ์ด์ ๊ฐ์ฅ ํฅ๋ฏธ๋ก์ด ๊ฒ์ผ๋ก ๋์ด ๊ฐ์๋ค.
๊ฐ์ ์ฅ์น
๋ฉํฐ์ค๋ ๋ฉ์๋ ๋ชจ๋ํฐ ๊ฐ๋ ์ด ํฌํจ๋ฉ๋๋ค. ๋ชจ๋ํฐ๋ผ๋ ๋จ์ด๋ 16์ธ๊ธฐ ๋ผํด์ด๋ฅผ ํตํด ์์ด๋ก ์์ผ๋ฉฐ "๊ณผ์ ์ ๊ด์ฐฐ, ํ์ธ ๋๋ ์ง์์ ์ผ๋ก ๊ธฐ๋กํ๋ ๋ฐ ์ฌ์ฉ๋๋ ๋๊ตฌ ๋๋ ์ฅ์น"๋ฅผ ์๋ฏธํฉ๋๋ค. ์ด ๊ธฐ์ฌ์ ๋งฅ๋ฝ์์ ๊ธฐ๋ณธ ์ฌํญ์ ๋ค๋ฃจ๋ ค๊ณ ๋ ธ๋ ฅํ ๊ฒ์ ๋๋ค. ์์ธํ ๋ด์ฉ์ ์ํ๋ ์ฌ๋์ ๋งํฌ๋ ์๋ฃ๋ฅผ ์ฐธ์กฐํ์ญ์์ค. JLS(Java Language Specification): 17.1๋ก ์ฌ์ ์ ์์ํฉ๋๋ค. ๋๊ธฐํ . ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
lock()
ํ๊ฑฐ๋ ํด์ ํ ์ ์์ต๋๋ค unlock()
. ๋ค์์ผ๋ก Oracle ์น ์ฌ์ดํธ์์ ์์ต์ Intrinsic Locks and Synchronization์ ์ฐพ์ ์ ์์ต๋๋ค.. ์ด ์์ต์์์๋ Java์ ๋๊ธฐํ๊ฐ ๊ณ ์ ์ ๊ธ ๋๋ ๋ชจ๋ํฐ ์ ๊ธ ์ด๋ผ๋ ๋ด๋ถ ์ํฐํฐ๋ฅผ ์ค์ฌ์ผ๋ก ๊ตฌ์ถ๋๋ค๊ณ ๋งํฉ๋๋ค . ์ด ์ ๊ธ ์ฅ์น๋ ์ข
์ข
๋จ์ํ " ๋ชจ๋ํฐ "๋ผ๊ณ ํฉ๋๋ค. ์ฐ๋ฆฌ๋ ๋ํ Java์ ๋ชจ๋ ๊ฐ์ฒด์ ๊ณ ์ ํ ์ ๊ธ์ด ์ฐ๊ฒฐ๋์ด ์์์ ๋ค์ ํ์ธํฉ๋๋ค. Java-Intrinsic Locks and Synchronization์ ์ฝ์ ์ ์์ต๋๋ค . ๋ค์์ผ๋ก Java์ ๊ฐ์ฒด๋ฅผ ๋ชจ๋ํฐ์ ์ฐ๊ฒฐํ๋ ๋ฐฉ๋ฒ์ ์ดํดํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค. Java์์ ๊ฐ ๊ฐ์ฒด์๋ ํ๋ก๊ทธ๋๋จธ๊ฐ ์ฝ๋์์ ์ฌ์ฉํ ์ ์์ง๋ง ๊ฐ์ ๋จธ์ ์ด ๊ฐ์ฒด์ ์ฌ๋ฐ๋ฅด๊ฒ ์๋ํ๋ ๋ฐ ํ์ํ ๋ด๋ถ ๋ฉํ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๋ ํค๋๊ฐ ์์ต๋๋ค. ๊ฐ์ฒด ํค๋์๋ ๋ค์๊ณผ ๊ฐ์ "ํ์ ๋จ์ด"๊ฐ ํฌํจ๋์ด ์์ต๋๋ค. 
https://edu.netbeans.org/contrib/slides/java-overview-and-java-se6.pdf
public class HelloWorld{
public static void main(String []args){
Object object = new Object();
synchronized(object) {
System.out.println("Hello World");
}
}
}
์ฌ๊ธฐ์ ํ์ฌ ์ค๋ ๋(์ด๋ฌํ ์ฝ๋ ํ์ด ์คํ๋๋ ์ค๋ ๋)๋ ํค์๋๋ฅผ ์ฌ์ฉ synchronized
ํ์ฌobject"\
์ ๊ธ์ ๊ฐ์ ธ์ค๊ฑฐ๋ ํ๋ํ๊ธฐ ์ํ ๋ณ์์
๋๋ค. ์๋ฌด๋ ๋ชจ๋ํฐ์ ๋ํด ๊ฒฝํฉํ์ง ์๋ ๊ฒฝ์ฐ(์ฆ, ๋์ผํ ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ์ฌ ๋๊ธฐํ๋ ์ฝ๋๋ฅผ ์คํํ๋ ์ฌ๋์ด ์๋ฌด๋ ์๋ ๊ฒฝ์ฐ) Java๋ "ํธํฅ๋ ์ ๊ธ"์ด๋ผ๋ ์ต์ ํ๋ฅผ ์ํํ๋ ค๊ณ ์๋ํ ์ ์์ต๋๋ค. ํด๋น ํ๊ทธ์ ์ค๋ ๋๊ฐ ๋ชจ๋ํฐ์ ์ ๊ธ์ ์์ ํ๋ ๋ ์ฝ๋์ ๋ํ ๋ ์ฝ๋๊ฐ ๊ฐ์ฒด ํค๋์ ๋งํฌ ์๋์ ์ถ๊ฐ๋ฉ๋๋ค. ์ด๋ ๊ฒ ํ๋ฉด ๋ชจ๋ํฐ๋ฅผ ์ ๊ทธ๋ ๋ฐ ํ์ํ ์ค๋ฒํค๋๊ฐ ์ค์ด๋ญ๋๋ค. ๋ชจ๋ํฐ๊ฐ ์ด์ ์ ๋ค๋ฅธ ์ค๋ ๋์ ์ํด ์์ ๋ ๊ฒฝ์ฐ ์ด๋ฌํ ์ ๊ธ์ผ๋ก๋ ์ถฉ๋ถํ์ง ์์ต๋๋ค. JVM์ ๋ค์ ์ ๊ธ ์ ํ์ธ "๊ธฐ๋ณธ ์ ๊ธ"์ผ๋ก ์ ํํฉ๋๋ค. CAS(๋น๊ต ๋ฐ ๊ตํ) ์์
์ ์ฌ์ฉํฉ๋๋ค. ๋ํ ๊ฐ์ฒด ํค๋์ ๋งํฌ ์๋ ์์ฒด๋ ๋ ์ด์ ๋งํฌ ์๋๋ฅผ ์ ์ฅํ์ง ์๊ณ ๋งํฌ ์๋๊ฐ ์ ์ฅ๋ ์์น์ ๋ํ ์ฐธ์กฐ๋ฅผ ์ ์ฅํ๋ฉฐ JVM์ด ๊ธฐ๋ณธ ์ ๊ธ์ ์ฌ์ฉํ๊ณ ์์์ ์ดํดํ ์ ์๋๋ก ํ๊ทธ๊ฐ ๋ณ๊ฒฝ๋ฉ๋๋ค. ์ฌ๋ฌ ์ค๋ ๋๊ฐ ๋ชจ๋ํฐ์ ๋ํด ๊ฒฝ์(๊ฒฝํฉ)ํ๋ ๊ฒฝ์ฐ(ํ๋๋ ์ ๊ธ์ ํ๋ํ๊ณ ๋ ๋ฒ์งธ ์ค๋ ๋๋ ์ ๊ธ์ด ํด์ ๋๊ธฐ๋ฅผ ๊ธฐ๋ค๋ฆฌ๊ณ ์์) ๋งํฌ ์๋์ ํ๊ทธ๊ฐ ๋ณ๊ฒฝ๋๊ณ ๋งํฌ ์๋๋ ์ด์ ๋ชจ๋ํฐ์ ๋ํ ์ฐธ์กฐ๋ฅผ ์ ์ฅํฉ๋๋ค. ๊ฐ์ฒด๋ก โ JVM์ ์ผ๋ถ ๋ด๋ถ ์ํฐํฐ์
๋๋ค. JDK Enchancement Proposal(JEP)์ ๋ช
์๋ ๋ฐ์ ๊ฐ์ด ์ด ์ํฉ์์๋ ์ด ์ํฐํฐ๋ฅผ ์ ์ฅํ๊ธฐ ์ํด ๋ฉ๋ชจ๋ฆฌ์ ๊ธฐ๋ณธ ํ ์์ญ์ ๊ณต๊ฐ์ด ํ์ํฉ๋๋ค. ์ด ๋ด๋ถ ์ํฐํฐ์ ๋ฉ๋ชจ๋ฆฌ ์์น์ ๋ํ ์ฐธ์กฐ๋ ๊ฐ์ฒด ํค๋์ ๋งํฌ ์๋์ ์ ์ฅ๋ฉ๋๋ค. ๋ฐ๋ผ์ ๋ชจ๋ํฐ๋ ์ค์ ๋ก ์ฌ๋ฌ ์ค๋ ๋ ๊ฐ์ ๊ณต์ ๋ฆฌ์์ค์ ๋ํ ์ก์ธ์ค๋ฅผ ๋๊ธฐํํ๊ธฐ ์ํ ๋ฉ์ปค๋์ฆ์
๋๋ค. JVM์ ์ด ๋ฉ์ปค๋์ฆ์ ์ฌ๋ฌ ๊ตฌํ ๊ฐ์ ์ ํํฉ๋๋ค. ๋ฐ๋ผ์ ๊ฐ๋จํ๊ฒ ๋ชจ๋ํฐ์ ๋ํด ์ด์ผ๊ธฐํ ๋ ์ค์ ๋ก๋ ์ ๊ธ์ ๋ํด ์ด์ผ๊ธฐํ๊ณ ์์ต๋๋ค. ๋ ๋ฒ์งธ๋ ์ ๊ธ์ด ํด์ ๋๊ธฐ๋ฅผ ๊ธฐ๋ค๋ฆฌ๊ณ ์์ต๋๋ค.) ๊ทธ๋ฐ ๋ค์ ๋งํฌ ์๋์ ํ๊ทธ๊ฐ ๋ณ๊ฒฝ๋๊ณ ๋งํฌ ์๋๋ ์ด์ ๋ชจ๋ํฐ์ ๋ํ ์ฐธ์กฐ๋ฅผ ๊ฐ์ฒด(JVM์ ์ผ๋ถ ๋ด๋ถ ์ํฐํฐ)๋ก ์ ์ฅํฉ๋๋ค. JDK Enchancement Proposal(JEP)์ ๋ช
์๋ ๋ฐ์ ๊ฐ์ด ์ด ์ํฉ์์๋ ์ด ์ํฐํฐ๋ฅผ ์ ์ฅํ๊ธฐ ์ํด ๋ฉ๋ชจ๋ฆฌ์ ๊ธฐ๋ณธ ํ ์์ญ์ ๊ณต๊ฐ์ด ํ์ํฉ๋๋ค. ์ด ๋ด๋ถ ์ํฐํฐ์ ๋ฉ๋ชจ๋ฆฌ ์์น์ ๋ํ ์ฐธ์กฐ๋ ๊ฐ์ฒด ํค๋์ ๋งํฌ ์๋์ ์ ์ฅ๋ฉ๋๋ค. ๋ฐ๋ผ์ ๋ชจ๋ํฐ๋ ์ค์ ๋ก ์ฌ๋ฌ ์ค๋ ๋ ๊ฐ์ ๊ณต์ ๋ฆฌ์์ค์ ๋ํ ์ก์ธ์ค๋ฅผ ๋๊ธฐํํ๊ธฐ ์ํ ๋ฉ์ปค๋์ฆ์
๋๋ค. JVM์ ์ด ๋ฉ์ปค๋์ฆ์ ์ฌ๋ฌ ๊ตฌํ ๊ฐ์ ์ ํํฉ๋๋ค. ๋ฐ๋ผ์ ๊ฐ๋จํ๊ฒ ๋ชจ๋ํฐ์ ๋ํด ์ด์ผ๊ธฐํ ๋ ์ค์ ๋ก๋ ์ ๊ธ์ ๋ํด ์ด์ผ๊ธฐํ๊ณ ์์ต๋๋ค. ๋ ๋ฒ์งธ๋ ์ ๊ธ์ด ํด์ ๋๊ธฐ๋ฅผ ๊ธฐ๋ค๋ฆฌ๊ณ ์์ต๋๋ค.) ๊ทธ๋ฐ ๋ค์ ๋งํฌ ์๋์ ํ๊ทธ๊ฐ ๋ณ๊ฒฝ๋๊ณ ๋งํฌ ์๋๋ ์ด์ ๋ชจ๋ํฐ์ ๋ํ ์ฐธ์กฐ๋ฅผ ๊ฐ์ฒด(JVM์ ์ผ๋ถ ๋ด๋ถ ์ํฐํฐ)๋ก ์ ์ฅํฉ๋๋ค. JDK Enchancement Proposal(JEP)์ ๋ช
์๋ ๋ฐ์ ๊ฐ์ด ์ด ์ํฉ์์๋ ์ด ์ํฐํฐ๋ฅผ ์ ์ฅํ๊ธฐ ์ํด ๋ฉ๋ชจ๋ฆฌ์ ๊ธฐ๋ณธ ํ ์์ญ์ ๊ณต๊ฐ์ด ํ์ํฉ๋๋ค. ์ด ๋ด๋ถ ์ํฐํฐ์ ๋ฉ๋ชจ๋ฆฌ ์์น์ ๋ํ ์ฐธ์กฐ๋ ๊ฐ์ฒด ํค๋์ ๋งํฌ ์๋์ ์ ์ฅ๋ฉ๋๋ค. ๋ฐ๋ผ์ ๋ชจ๋ํฐ๋ ์ค์ ๋ก ์ฌ๋ฌ ์ค๋ ๋ ๊ฐ์ ๊ณต์ ๋ฆฌ์์ค์ ๋ํ ์ก์ธ์ค๋ฅผ ๋๊ธฐํํ๊ธฐ ์ํ ๋ฉ์ปค๋์ฆ์
๋๋ค. JVM์ ์ด ๋ฉ์ปค๋์ฆ์ ์ฌ๋ฌ ๊ตฌํ ๊ฐ์ ์ ํํฉ๋๋ค. ๋ฐ๋ผ์ ๊ฐ๋จํ๊ฒ ๋ชจ๋ํฐ์ ๋ํด ์ด์ผ๊ธฐํ ๋ ์ค์ ๋ก๋ ์ ๊ธ์ ๋ํด ์ด์ผ๊ธฐํ๊ณ ์์ต๋๋ค. ๋งํฌ ์๋๋ ์ด์ ๋ชจ๋ํฐ์ ๋ํ ์ฐธ์กฐ๋ฅผ ๊ฐ์ฒด(JVM์ ์ผ๋ถ ๋ด๋ถ ์ํฐํฐ)๋ก ์ ์ฅํฉ๋๋ค. JDK Enchancement Proposal(JEP)์ ๋ช
์๋ ๋ฐ์ ๊ฐ์ด ์ด ์ํฉ์์๋ ์ด ์ํฐํฐ๋ฅผ ์ ์ฅํ๊ธฐ ์ํด ๋ฉ๋ชจ๋ฆฌ์ ๊ธฐ๋ณธ ํ ์์ญ์ ๊ณต๊ฐ์ด ํ์ํฉ๋๋ค. ์ด ๋ด๋ถ ์ํฐํฐ์ ๋ฉ๋ชจ๋ฆฌ ์์น์ ๋ํ ์ฐธ์กฐ๋ ๊ฐ์ฒด ํค๋์ ๋งํฌ ์๋์ ์ ์ฅ๋ฉ๋๋ค. ๋ฐ๋ผ์ ๋ชจ๋ํฐ๋ ์ค์ ๋ก ์ฌ๋ฌ ์ค๋ ๋ ๊ฐ์ ๊ณต์ ๋ฆฌ์์ค์ ๋ํ ์ก์ธ์ค๋ฅผ ๋๊ธฐํํ๊ธฐ ์ํ ๋ฉ์ปค๋์ฆ์
๋๋ค. JVM์ ์ด ๋ฉ์ปค๋์ฆ์ ์ฌ๋ฌ ๊ตฌํ ๊ฐ์ ์ ํํฉ๋๋ค. ๋ฐ๋ผ์ ๊ฐ๋จํ๊ฒ ๋ชจ๋ํฐ์ ๋ํด ์ด์ผ๊ธฐํ ๋ ์ค์ ๋ก๋ ์ ๊ธ์ ๋ํด ์ด์ผ๊ธฐํ๊ณ ์์ต๋๋ค. ๋งํฌ ์๋๋ ์ด์ ๋ชจ๋ํฐ์ ๋ํ ์ฐธ์กฐ๋ฅผ ๊ฐ์ฒด(JVM์ ์ผ๋ถ ๋ด๋ถ ์ํฐํฐ)๋ก ์ ์ฅํฉ๋๋ค. JDK Enchancement Proposal(JEP)์ ๋ช
์๋ ๋ฐ์ ๊ฐ์ด ์ด ์ํฉ์์๋ ์ด ์ํฐํฐ๋ฅผ ์ ์ฅํ๊ธฐ ์ํด ๋ฉ๋ชจ๋ฆฌ์ ๊ธฐ๋ณธ ํ ์์ญ์ ๊ณต๊ฐ์ด ํ์ํฉ๋๋ค. ์ด ๋ด๋ถ ์ํฐํฐ์ ๋ฉ๋ชจ๋ฆฌ ์์น์ ๋ํ ์ฐธ์กฐ๋ ๊ฐ์ฒด ํค๋์ ๋งํฌ ์๋์ ์ ์ฅ๋ฉ๋๋ค. ๋ฐ๋ผ์ ๋ชจ๋ํฐ๋ ์ค์ ๋ก ์ฌ๋ฌ ์ค๋ ๋ ๊ฐ์ ๊ณต์ ๋ฆฌ์์ค์ ๋ํ ์ก์ธ์ค๋ฅผ ๋๊ธฐํํ๊ธฐ ์ํ ๋ฉ์ปค๋์ฆ์
๋๋ค. JVM์ ์ด ๋ฉ์ปค๋์ฆ์ ์ฌ๋ฌ ๊ตฌํ ๊ฐ์ ์ ํํฉ๋๋ค. ๋ฐ๋ผ์ ๊ฐ๋จํ๊ฒ ๋ชจ๋ํฐ์ ๋ํด ์ด์ผ๊ธฐํ ๋ ์ค์ ๋ก๋ ์ ๊ธ์ ๋ํด ์ด์ผ๊ธฐํ๊ณ ์์ต๋๋ค. ์ด ๋ด๋ถ ์ํฐํฐ์ ๋ฉ๋ชจ๋ฆฌ ์์น์ ๋ํ ์ฐธ์กฐ๋ ๊ฐ์ฒด ํค๋์ ๋งํฌ ์๋์ ์ ์ฅ๋ฉ๋๋ค. ๋ฐ๋ผ์ ๋ชจ๋ํฐ๋ ์ค์ ๋ก ์ฌ๋ฌ ์ค๋ ๋ ๊ฐ์ ๊ณต์ ๋ฆฌ์์ค์ ๋ํ ์ก์ธ์ค๋ฅผ ๋๊ธฐํํ๊ธฐ ์ํ ๋ฉ์ปค๋์ฆ์
๋๋ค. JVM์ ์ด ๋ฉ์ปค๋์ฆ์ ์ฌ๋ฌ ๊ตฌํ ๊ฐ์ ์ ํํฉ๋๋ค. ๋ฐ๋ผ์ ๊ฐ๋จํ๊ฒ ๋ชจ๋ํฐ์ ๋ํด ์ด์ผ๊ธฐํ ๋ ์ค์ ๋ก๋ ์ ๊ธ์ ๋ํด ์ด์ผ๊ธฐํ๊ณ ์์ต๋๋ค. ์ด ๋ด๋ถ ์ํฐํฐ์ ๋ฉ๋ชจ๋ฆฌ ์์น์ ๋ํ ์ฐธ์กฐ๋ ๊ฐ์ฒด ํค๋์ ๋งํฌ ์๋์ ์ ์ฅ๋ฉ๋๋ค. ๋ฐ๋ผ์ ๋ชจ๋ํฐ๋ ์ค์ ๋ก ์ฌ๋ฌ ์ค๋ ๋ ๊ฐ์ ๊ณต์ ๋ฆฌ์์ค์ ๋ํ ์ก์ธ์ค๋ฅผ ๋๊ธฐํํ๊ธฐ ์ํ ๋ฉ์ปค๋์ฆ์
๋๋ค. JVM์ ์ด ๋ฉ์ปค๋์ฆ์ ์ฌ๋ฌ ๊ตฌํ ๊ฐ์ ์ ํํฉ๋๋ค. ๋ฐ๋ผ์ ๊ฐ๋จํ๊ฒ ๋ชจ๋ํฐ์ ๋ํด ์ด์ผ๊ธฐํ ๋ ์ค์ ๋ก๋ ์ ๊ธ์ ๋ํด ์ด์ผ๊ธฐํ๊ณ ์์ต๋๋ค. 
๋๊ธฐํ๋จ(์ ๊ธ ๋๊ธฐ ์ค)
์์์ ๋ณด์๋ฏ์ด "๋๊ธฐํ ๋ธ๋ก"(๋๋ "์๊ณ ์์ญ")์ ๊ฐ๋ ์ ๋ชจ๋ํฐ์ ๊ฐ๋ ๊ณผ ๋ฐ์ ํ ๊ด๋ จ์ด ์์ต๋๋ค. ์๋ฅผ ์ดํด๋ณด์ญ์์ค.
public static void main(String[] args) throws InterruptedException {
Object lock = new Object();
Runnable task = () -> {
synchronized(lock) {
System.out.println("thread");
}
};
Thread th1 = new Thread(task);
th1.start();
synchronized(lock) {
for (int i = 0; i < 8; i++) {
Thread.currentThread().sleep(1000);
System.out.print(" " + i);
}
System.out.println(" ...");
}
}
์ฌ๊ธฐ์ ๋ฉ์ธ ์ฐ๋ ๋๋ ๋จผ์ ์์
๊ฐ์ฒด๋ฅผ ์ ์ฐ๋ ๋์๊ฒ ์ ๋ฌํ ํ ์ฆ์ ์ ๊ธ์ ํ๋ํ๊ณ ์ด๋ฅผ ๊ฐ์ง๊ณ ๊ธด ์์
์ ์ํํฉ๋๋ค(8์ด). synchronized
์ด ๋ชจ๋ ์๊ฐ ๋์ ์์
์ ์ด๋ฏธ ์ ๊ธ์ ํ๋ํ๊ธฐ ๋๋ฌธ์ ๋ธ๋ก ์ ๋ค์ด๊ฐ ์ ์๊ธฐ ๋๋ฌธ์ ์์
์ ์งํํ ์ ์์ต๋๋ค . ์ค๋ ๋๊ฐ ์ ๊ธ์ ์ป์ ์ ์์ผ๋ฉด ๋ชจ๋ํฐ๋ฅผ ๊ธฐ๋ค๋ฆฝ๋๋ค. ์ ๊ธ์ ํ๋ณดํ๋ ์ฆ์ ์คํ์ ๊ณ์ํฉ๋๋ค. ์ค๋ ๋๊ฐ ๋ชจ๋ํฐ๋ฅผ ์ข
๋ฃํ๋ฉด ์ ๊ธ์ด ํด์ ๋ฉ๋๋ค. JVisualVM์์๋ ๋ค์๊ณผ ๊ฐ์ด ํ์๋ฉ๋๋ค. 
th1.getState()
for ๋ฃจํ์ ๋ช
๋ น๋ฌธ์ BLOCKED ๋ฅผ ๋ฐํํฉ๋๋ค . ๋ฃจํ๊ฐ ์คํ๋๋ ๋์ ๊ฐ์ฒด์ ๋ชจ๋ํฐ๋ ์ค๋ ๋ lock
์ ์ํด ์ ์ ๋๊ณ ์ค๋ ๋๋ ์ฐจ๋จ๋์ด ์ ๊ธ์ด ํด์ ๋ ๋๊น์ง ์งํํ ์ ์๊ธฐ ๋๋ฌธ์
๋๋ค. ๋๊ธฐํ๋ ๋ธ๋ก ์ธ์๋ ์ ์ฒด ๋ถ์๋ฒ์ ๋๊ธฐํํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด ๋ค์์ ํด๋์ค์ ๋ฉ์๋์
๋๋ค . main
th1
HashTable
public synchronized int size() {
return count;
}
์ด ๋ฉ์๋๋ ์ฃผ์ด์ง ์๊ฐ์ ํ๋์ ์ค๋ ๋์์๋ง ์คํ๋ฉ๋๋ค. ์๋ฌผ์ ๊ฐ ์ ๋ง ํ์ํ๊ฐ์? ์, ํ์ํฉ๋๋ค. ์ธ์คํด์ค ๋ฉ์๋์ ๊ฒฝ์ฐ "์ด" ๊ฐ์ฒด(ํ์ฌ ๊ฐ์ฒด)๊ฐ ์ ๊ธ ์ญํ ์ ํฉ๋๋ค. ์ฌ๊ธฐ ์ด ์ฃผ์ ์ ๋ํ ํฅ๋ฏธ๋ก์ด ๋
ผ์๊ฐ ์์ต๋๋ค. ๋๊ธฐํ๋ ๋ธ๋ก ๋์ ๋๊ธฐํ๋ ๋ฐฉ๋ฒ์ ์ฌ์ฉํ๋ฉด ์ด์ ์ด ์์ต๋๊น? . ๋ฉ์๋๊ฐ ์ ์ ์ด๋ฉด ์ ๊ธ์ "this" ๊ฐ์ฒด๊ฐ ์๋๋ผ(์ ์ ๋ฉ์๋์ ๋ํ "this" ๊ฐ์ฒด๊ฐ ์๊ธฐ ๋๋ฌธ์) Class ๊ฐ์ฒด(์: )๊ฐ ๋ฉ๋๋ค Integer.class
.
๊ธฐ๋ค๋ฆฌ์ญ์์ค(๋ชจ๋ํฐ ๋๊ธฐ ์ค). notify() ๋ฐ notifyAll() ๋ฉ์๋
Thread ํด๋์ค์๋ ๋ชจ๋ํฐ์ ์ฐ๊ฒฐ๋ ๋ ๋ค๋ฅธ ๋๊ธฐ ๋ฉ์๋๊ฐ ์์ต๋๋ค.sleep()
๋ฐ ์ ๋ฌ๋ฆฌ join()
์ด ๋ฉ์๋๋ ๋จ์ํ ํธ์ถํ ์ ์์ต๋๋ค. ๊ทธ ์ด๋ฆ์ wait()
. ์ด wait
๋ฉ์๋๋ ๊ธฐ๋ค๋ฆฌ๋ ค๋ ๋ชจ๋ํฐ์ ์ฐ๊ฒฐ๋ ๊ฐ์ฒด์์ ํธ์ถ๋ฉ๋๋ค. ์๋ฅผ ๋ณด์:
public static void main(String []args) throws InterruptedException {
Object lock = new Object();
// The task object will wait until it is notified via lock
Runnable task = () -> {
synchronized(lock) {
try {
lock.wait();
} catch(InterruptedException e) {
System.out.println("interrupted");
}
}
// After we are notified, we will wait until we can acquire the lock
System.out.println("thread");
};
Thread taskThread = new Thread(task);
taskThread.start();
// We sleep. Then we acquire the lock, notify, and release the lock
Thread.currentThread().sleep(3000);
System.out.println("main");
synchronized(lock) {
lock.notify();
}
}
JVisualVM์์๋ ๋ค์๊ณผ ๊ฐ์ด ํ์๋ฉ๋๋ค. 
wait()
๋ฐ notify()
๋ฉ์๋๊ฐ ์ ์ฐ๊ฒฐ๋์ด ์์ ์ ๊ธฐ์ตํ์ญ์์ค java.lang.Object
. ์ค๋ ๋ ๊ด๋ จ ๋ฉ์๋๊ฐ Object
ํด๋์ค์ ์๋ ๊ฒ์ด ์ด์ํ๊ฒ ๋ณด์ผ ์ ์์ต๋๋ค. ๊ทธ๋ฌ๋ ์ด์ ๊ทธ ์ด์ ๊ฐ ๋ฐํ์ง๋๋ค. Java์ ๋ชจ๋ ๊ฐ์ฒด์๋ ํค๋๊ฐ ์๋ค๋ ๊ฒ์ ๊ธฐ์ตํ ๊ฒ์
๋๋ค. ํค๋์๋ ๋ชจ๋ํฐ์ ๋ํ ์ ๋ณด(์: ์ ๊ธ ์ํ)๋ฅผ ํฌํจํ์ฌ ๋ค์ํ ๊ด๋ฆฌ ์ ๋ณด๊ฐ ํฌํจ๋์ด ์์ต๋๋ค. ๊ฐ ๊ฐ์ฒด ๋๋ ํด๋์ค์ ์ธ์คํด์ค๋ ๊ณ ์ ์ ๊ธ ๋๋ ๋ชจ๋ํฐ๋ผ๊ณ ํ๋ JVM์ ๋ด๋ถ ์ํฐํฐ์ ์ฐ๊ฒฐ๋์ด ์์ต๋๋ค. ์์ ์์์ ์์
๊ฐ์ฒด์ ๋ํ ์ฝ๋๋ ๊ฐ์ฒด์ ์ฐ๊ฒฐ๋ ๋ชจ๋ํฐ์ ๋ํด ๋๊ธฐํ๋ ๋ธ๋ก์ ์
๋ ฅํ์์ ๋ํ๋
๋๋ค lock
. ์ด ๋ชจ๋ํฐ์ ๋ํ ์ ๊ธ ํ๋์ ์ฑ๊ณตํ๋ฉดwait()
ํธ์ถ๋ฉ๋๋ค. ์์
์ ์คํํ๋ ์ค๋ ๋๋ lock
๊ฐ์ฒด์ ๋ชจ๋ํฐ๋ฅผ ํด์ ํ์ง๋ง ๊ฐ์ฒด์ ๋ชจ๋ํฐ์์ ์๋ฆผ์ ๊ธฐ๋ค๋ฆฌ๋ ์ค๋ ๋ ๋๊ธฐ์ด์ ๋ค์ด๊ฐ๋๋ค lock
. ์ด ์ค๋ ๋ ๋๊ธฐ์ด์ WAIT SET์ด๋ผ๊ณ ํ๋ฉฐ ๊ทธ ๋ชฉ์ ์ ๋ ์ ์ ํ๊ฒ ๋ฐ์ํฉ๋๋ค. ์ฆ, ๋๊ธฐ์ด๋ณด๋ค ์งํฉ์ ๊ฐ๊น์ต๋๋ค. ์ค๋ ๋ main
๋ ์์
๊ฐ์ฒด๋ก ์ ์ค๋ ๋๋ฅผ ๋ง๋ค๊ณ ์์ํ๊ณ 3์ด ๋์ ๊ธฐ๋ค๋ฆฝ๋๋ค. ์ด๋ ๊ฒ ํ๋ฉด ์ ์ค๋ ๋๊ฐ ์ค๋ ๋๋ณด๋ค ๋จผ์ ์ ๊ธ์ ํ๋ main
ํ๊ณ ๋ชจ๋ํฐ ํ์ ๋ค์ด๊ฐ ๊ฐ๋ฅ์ฑ์ด ๋์์ง๋๋ค. ๊ทธ๋ฐ ๋ค์ main
์ค๋ ๋ ์์ฒด๊ฐ ๊ฐ์ฒด์ ๋๊ธฐํ ๋ธ๋ก์ ๋ค์ด๊ฐ lock
๋ชจ๋ํฐ๋ฅผ ์ฌ์ฉํ์ฌ ์ค๋ ๋ ์๋ฆผ์ ์ํํฉ๋๋ค. ์๋ฆผ์ด ์ ์ก๋ ํ main
์ค๋ ๋๋lock
lock
๊ฐ์ฒด์ ๋ชจ๋ํฐ์ ์ด์ ์ ๊ฐ์ฒด์ ๋ชจ๋ํฐ๊ฐ ํด์ ๋๊ธฐ๋ฅผ ๊ธฐ๋ค๋ฆฌ๊ณ ์๋ ์ ์ค๋ ๋๊ฐ ์คํ์ ๊ณ์ํฉ๋๋ค. notify()
ํ๋์ ์ค๋ ๋( )์๋ง ์๋ฆผ์ ๋ณด๋ด๊ฑฐ๋ ๋๊ธฐ์ด์ ๋ชจ๋ ์ค๋ ๋( )์ ๋์์ ์๋ฆผ์ ๋ณด๋ผ ์ ์์ต๋๋ค notifyAll()
. ์์ธํ ๋ด์ฉ์ Java์์ notify()์ notifyAll()์ ์ฐจ์ด์ ์ ์ฐธ์กฐํ์ญ์์ค . ์๋ฆผ ์์๋ JVM์ด ๊ตฌํ๋๋ ๋ฐฉ์์ ๋ฐ๋ผ ๋ค๋ฅด๋ค๋ ์ ์ ์ ์ํด์ผ ํฉ๋๋ค. ์์ธํ ๋ด์ฉ์ ์ฌ๊ธฐ๋ฅผ ์ฐธ์กฐํ์ญ์์ค. notify ๋ฐ notifyAll์ ์ฌ์ฉํ์ฌ ๊ธฐ์ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ๋ฐฉ๋ฒ์ ๋ฌด์์
๋๊น? . ๊ฐ์ฒด๋ฅผ ์ง์ ํ์ง ์๊ณ ๋๊ธฐํ๋ฅผ ์ํํ ์ ์์ต๋๋ค. ๋จ์ผ ์ฝ๋ ๋ธ๋ก์ด ์๋ ์ ์ฒด ๋ฉ์๋๊ฐ ๋๊ธฐํ๋ ๋ ์ด ์์
์ ์ํํ ์ ์์ต๋๋ค. .class
์๋ฅผ ๋ค์ด, ์ ์ ๋ฉ์๋์ ๊ฒฝ์ฐ ์ ๊ธ์ Class ๊ฐ์ฒด(๋ฅผ ํตํด ์ป์ ) ๊ฐ ๋ฉ๋๋ค .
public static synchronized void printA() {
System.out.println("A");
}
public static void printB() {
synchronized(HelloWorld.class) {
System.out.println("B");
}
}
์ ๊ธ ์ฌ์ฉ ์ธก๋ฉด์์ ๋ ๋ฐฉ๋ฒ์ ๋์ผํฉ๋๋ค. instance
๋ฉ์๋๊ฐ ์ ์ ์ด ์๋ ๊ฒฝ์ฐ ํ์ฌ , ์ฆ ๋ฅผ ์ฌ์ฉ ํ์ฌ ๋๊ธฐํ๊ฐ ์ํ๋ฉ๋๋ค this
. ๊ทธ๊ฑด ๊ทธ๋ ๊ณ , ์ฐ๋ฆฌ๋ ์ด์ ์ ์ด getState()
๋ฉ์๋๋ฅผ ์ฌ์ฉํ์ฌ ์ค๋ ๋์ ์ํ๋ฅผ ์ป์ ์ ์๋ค๊ณ ๋งํ์ต๋๋ค. ์๋ฅผ ๋ค์ด ๋ชจ๋ํฐ๋ฅผ ๊ธฐ๋ค๋ฆฌ๋ ๋๊ธฐ์ด์ ์ค๋ ๋์ ๊ฒฝ์ฐ ๋ฉ์๋๊ฐ wait()
์๊ฐ ์ด๊ณผ๋ฅผ ์ง์ ํ ๊ฒฝ์ฐ ์ํ๋ WAITING ๋๋ TIMED_WAITING์ด ๋ฉ๋๋ค. 
https://stackoverflow.com/questions/36425942/what-is-the-lifecycle-of-thread-in-java
์ค๋ ๋ ์๋ช ์ฃผ๊ธฐ
์๋ช ์ด ๋คํ๋ ๋์ ์ค๋ ๋์ ์ํ๊ฐ ๋ณ๊ฒฝ๋ฉ๋๋ค. ์ค์ ๋ก ์ด๋ฌํ ๋ณ๊ฒฝ ์ฌํญ์ ์ค๋ ๋์ ์๋ช ์ฃผ๊ธฐ๋ฅผ ๊ตฌ์ฑํฉ๋๋ค. ์ค๋ ๋๊ฐ ์์ฑ๋์๋ง์ ์ํ๋ NEW์ ๋๋ค. ์ด ์ํ์์ ์ ์ค๋ ๋๋ ์์ง ์คํ ์ค์ด ์๋๋ฉฐ Java ์ค๋ ๋ ์ค์ผ์ค๋ฌ๋ ์์ง ์ด์ ๋ํด ์๋ฌด๊ฒ๋ ์์ง ๋ชปํฉ๋๋ค. ์ค๋ ๋ ์ค์ผ์ค๋ฌ๊ฐ ์ค๋ ๋์ ๋ํด ํ์ตํ๋ ค๋ฉดthread.start()
๋ฉ์๋๋ฅผ ํธ์ถํด์ผ ํฉ๋๋ค. ๊ทธ๋ฐ ๋ค์ ์ค๋ ๋๋ RUNNABLE ์ํ๋ก ์ ํ๋ฉ๋๋ค. ์ธํฐ๋ท์๋ "์คํ ๊ฐ๋ฅ" ์ํ์ "์คํ ์ค" ์ํ๋ฅผ ๊ตฌ๋ถํ๋ ์๋ชป๋ ๋ค์ด์ด๊ทธ๋จ์ด ๋ง์ด ์์ต๋๋ค. ๊ทธ๋ฌ๋ ์ด๊ฒ์ ์ค์์
๋๋ค. Java๋ "์์
์ค๋น"(์คํ ๊ฐ๋ฅ)์ "์์
"(์คํ ์ค)์ ๊ตฌ๋ถํ์ง ์๊ธฐ ๋๋ฌธ์
๋๋ค. ์ค๋ ๋๊ฐ ํ์ฑ ์ํ์ด์ง๋ง ํ์ฑํ๋์ง ์์ ๊ฒฝ์ฐ(์คํ ๊ฐ๋ฅํ์ง ์์ ๊ฒฝ์ฐ) ๋ค์ ๋ ๊ฐ์ง ์ํ ์ค ํ๋์
๋๋ค.
- BLOCKED โ ํฌ๋ฆฌํฐ์ปฌ ์น์
, ์ฆ
synchronized
๋ธ๋ก์ ์ง์ ํ๊ธฐ ์ํด ๋๊ธฐ ์ค์ ๋๋ค. - WAITING โ ๋ค๋ฅธ ์ค๋ ๋๊ฐ ์ด๋ค ์กฐ๊ฑด์ ๋ง์กฑ์ํค๊ธฐ๋ฅผ ๊ธฐ๋ค๋ฆฝ๋๋ค.
getState()
๋ฉ์๋๋ฅผ ์ฌ์ฉํ์ญ์์ค. isAlive()
์ค๋ ๋์๋ ์ค๋ ๋๊ฐ ์ข
๋ฃ๋์ง ์์ ๊ฒฝ์ฐ true๋ฅผ ๋ฐํํ๋ ๋ฉ์๋ ๋ ์์ต๋๋ค .
LockSupport ๋ฐ ์ค๋ ๋ ํํน
Java 1.6๋ถํฐ LockSupport ๋ผ๋ ํฅ๋ฏธ๋ก์ด ๋ฉ์ปค๋์ฆ์ด ๋ฑ์ฅํ์ต๋๋ค.
park()
ํ๊ฐ๊ฐ ์ฌ์ฉ ๊ฐ๋ฅํ ๊ฒฝ์ฐ ์ฆ์ ๋ฐํ๋์ด ํ๋ก์ธ์ค์์ ํ๊ฐ๋ฅผ ์๋นํฉ๋๋ค. ๊ทธ๋ ์ง ์์ผ๋ฉด ์ฐจ๋จ๋ฉ๋๋ค. ๋ฉ์๋๋ฅผ ํธ์ถํ๋ฉด unpark
์์ง ์ฌ์ฉํ ์ ์๋ ๊ฒฝ์ฐ ํ๊ฐ๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค. ํ๊ฐ์ฆ์ 1๊ฐ๋ฟ์ด๋ค. ์ ๋ํ Java ๋ฌธ์๋ ํด๋์ค๋ฅผ LockSupport
์ฐธ์กฐํฉ๋๋ค Semaphore
. ๊ฐ๋จํ ์๋ฅผ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
import java.util.concurrent.Semaphore;
public class HelloWorldApp{
public static void main(String[] args) {
Semaphore semaphore = new Semaphore(0);
try {
semaphore.acquire();
} catch (InterruptedException e) {
// Request the permit and wait until we get it
e.printStackTrace();
}
System.out.println("Hello, World!");
}
}
์ด์ ์ธ๋งํฌ์ด์ 0๊ฐ์ ํ๊ฐ๊ฐ ์๊ธฐ ๋๋ฌธ์ ์ด ์ฝ๋๋ ํญ์ ๋๊ธฐํฉ๋๋ค. ๊ทธ๋ฆฌ๊ณ acquire()
์ฝ๋์์ ๊ฐ ํธ์ถ๋๋ฉด(์: ํ๊ฐ ์์ฒญ) ์ค๋ ๋๋ ํ๊ฐ๋ฅผ ๋ฐ์ ๋๊น์ง ๊ธฐ๋ค๋ฆฝ๋๋ค. ์ฐ๋ฆฌ๋ ๊ธฐ๋ค๋ฆฌ๊ณ ์๊ธฐ ๋๋ฌธ์ ์ฒ๋ฆฌํด์ผ ํฉ๋๋ค InterruptedException
. ํฅ๋ฏธ๋กญ๊ฒ๋ ์ธ๋งํฌ์ด๋ ๋ณ๋์ ์ค๋ ๋ ์ํ๋ฅผ ๊ฐ์ต๋๋ค. JVisualVM์ ๋ณด๋ฉด ์ํ๊ฐ "Wait"์ด ์๋๋ผ "Park"์์ ์ ์ ์์ต๋๋ค. 
public static void main(String[] args) throws InterruptedException {
Runnable task = () -> {
// Park the current thread
System.err.println("Will be Parked");
LockSupport.park();
// As soon as we are unparked, we will start to act
System.err.println("Unparked");
};
Thread th = new Thread(task);
th.start();
Thread.currentThread().sleep(2000);
System.err.println("Thread state: " + th.getState());
LockSupport.unpark(th);
Thread.currentThread().sleep(2000);
}
์ค๋ ๋์ ์ํ๋ WAITING์ด์ง๋ง JVisualVM์ wait
ํค์๋ synchronized
์ park
ํด๋์ค ๋ฅผ ๊ตฌ๋ณํฉ๋๋ค LockSupport
. ์ด๊ฒ์ด ์ LockSupport
๊ทธ๋ ๊ฒ ์ค์ํ๊ฐ์? Java ๋ฌธ์๋ก ๋ค์ ๋์๊ฐ์ WAITING ์ค๋ ๋ ์ํ๋ฅผ ์ดํด๋ด
๋๋ค. ๋ณด์๋ค์ํผ, ๋ค์ด๊ฐ๋ ๋ฐฉ๋ฒ์ ์ธ ๊ฐ์ง๋ฟ์
๋๋ค. ๊ทธ ๋ ๊ฐ์ง ๋ฐฉ๋ฒ์ wait()
๋ฐ ์
๋๋ค join()
. ๊ทธ๋ฆฌ๊ณ ์ธ ๋ฒ์งธ๋ LockSupport
. Java์์ ์ ๊ธ์ t์ ๊ตฌ์ถ๋ ์ LockSuppor
์์ผ๋ฉฐ ๋ ๋์ ์์ค์ ๋๊ตฌ๋ฅผ ์ ๊ณตํฉ๋๋ค. ํ ๋ฒ ์ฌ์ฉํด ๋ด
์๋ค. ์๋ฅผ ๋ค์ด ๋ค์์ ์ดํด๋ณด์ญ์์ค ReentrantLock
.
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class HelloWorld{
public static void main(String []args) throws InterruptedException {
Lock lock = new ReentrantLock();
Runnable task = () -> {
lock.lock();
System.out.println("Thread");
lock.unlock();
};
lock.lock();
Thread th = new Thread(task);
th.start();
System.out.println("main");
Thread.currentThread().sleep(2000);
lock.unlock();
}
}
์์ ์์์์ ๋ง์ฐฌ๊ฐ์ง๋ก ์ฌ๊ธฐ์๋ ๋ชจ๋ ๊ฒ์ด ๊ฐ๋จํฉ๋๋ค. ๊ฐ์ฒด lock
๋ ๋๊ตฐ๊ฐ๊ฐ ๊ณต์ ๋ฆฌ์์ค๋ฅผ ํด์ ํ๊ธฐ๋ฅผ ๊ธฐ๋ค๋ฆฝ๋๋ค. JVisualVM์ ๋ณด๋ฉด ์ค๋ ๋๊ฐ main
์ ๊ธ์ ํด์ ํ ๋๊น์ง ์ ์ค๋ ๋๊ฐ ํํน๋๋ ๊ฒ์ ๋ณผ ์ ์์ต๋๋ค. ์ ๊ธ์ ๋ํ ์์ธํ ๋ด์ฉ์ Java 8 StampedLocks ๋ ReadWriteLocks and Synchronized and Lock API in Java์์ ํ์ธํ ์ ์์ต๋๋ค. ์ ๊ธ์ด ๊ตฌํ๋๋ ๋ฐฉ์์ ๋ ์ ์ดํดํ๋ ค๋ฉด Java Phaser ๊ฐ์ด๋ ๋ฌธ์์์ Phaser์ ๋ํด ์ฝ์ด๋ณด๋ ๊ฒ์ด ์ข์ต๋๋ค . ๊ทธ๋ฆฌ๊ณ ๋ค์ํ ๋๊ธฐํ ํ๋ก๊ทธ๋จ์ ๋ํด ๋งํ์๋ฉด The Java Synchronizers์ ๋ํ DZone ๊ธฐ์ฌ๋ฅผ ์ฝ์ด์ผ ํฉ๋๋ค .
๊ฒฐ๋ก
์ด ๋ฆฌ๋ทฐ์์๋ ์ค๋ ๋๊ฐ Java์์ ์ํธ ์์ฉํ๋ ์ฃผ์ ๋ฐฉ์์ ์กฐ์ฌํ์ต๋๋ค. ์ถ๊ฐ ์๋ฃ:- ๋ ๋์ ์กฐํฉ: Java์ Thread ํด๋์ค. ํํธ I โ ์คํ ์ค๋ ๋
- https://dzone.com/articles/the-java-synchronizers
- https://www.javatpoint.com/java-multithreading-interview-questions
GO TO FULL VERSION