๋ค์๊ณผ ๊ฐ์ ์์ผ๋ก ๊ธ์ด ์ด์ด์ง๋๋ค.
synchronized ์๊ฐ
synchronized vs static synchronized
synchronized ๋จ์ ์ ๊ทน๋ณตํ ReentrantLock ์๊ฐ
synchronized vs ReentrantLock
1. synchronized ์๊ฐ
๋ฉํฐ์ค๋ ๋ ํ๊ฒฝ์์๋ ์ฌ๋ฌ ์ค๋ ๋๊ฐ ๋์์ ๊ฐ์ ์์์ ์ ๊ทผํ ๊ฒฝ์ฐ, ์์์น ๋ชปํ ๋ฌธ์ (๋ฐ์ดํฐ ์์, ์ถฉ๋ ๋ฑ)๊ฐ ๋ฐ์ํ ์ ์์ต๋๋ค. ์ด๋ฅผ ๋ฐฉ์งํ๊ธฐ ์ํด ๋๊ธฐํ(synchronization) ๊ธฐ๋ฒ์ด ํ์ํฉ๋๋ค.
Java์์ ์ ๊ณตํ๋ synchronized ํค์๋๋ ๋ชจ๋ํฐ ๋ฝ(Monitor Lock)์ ์ด์ฉํด ๋๊ธฐํ๋ฅผ ์ง์ํฉ๋๋ค.
๋ชจ๋ํฐ๋ OS๊ฐ ์๋ ํ๋ก๊ทธ๋๋ฐ ์ธ์ด ์์ค์์ ์ ๊ณตํ๋ ๋๊ธฐํ ๋ฉ์ปค๋์ฆ์ ๋๋ค. Java์ ๋ชจ๋ ๊ฐ์ฒด(์ธ์คํด์ค)๋ ๋ด๋ถ์ ์ผ๋ก ๊ณ ์ ํ ๋ชจ๋ํฐ๋ฅผ ๊ฐ์ง๋ฉฐ, ์ด๋ฅผ ํ๋ํ๊ณ ํด์ ํ๋ฉฐ ๋๊ธฐํ ์์ ์ ์ํํฉ๋๋ค. ์ฆ, ๋ชจ๋ํฐ์ ๋ฝ์ ์๋ก ์ํธ๋ณด์์ ์ธ ๊ด๊ณ๋ก ๋์ฒดํ๊ฑฐ๋ ๋น๊ตํ ์ ์๋ ๊ฐ๋ ์ด ์๋๋๋ค.
- ์ถ์ฒ : In Java, what is the difference between a monitor and a lock
synchronized ํน์ง
- ์ค๋ ๋๊ฐ synchronized ํค์๋๊ฐ ๋ถ์ ๋ฉ์๋์ ์ง์ ํ๋ ค๋ฉด ํด๋น ๊ฐ์ฒด์ ๋ฝ์ ํ๋ํด์ผ ํฉ๋๋ค.
- ๋ฝ์ ํ๋ํ์ง ๋ชปํ ์ค๋ ๋๋ RUNNABLE ์ํ์์ BLOCKED ์ํ๋ก ์ ํ๋ฉ๋๋ค. ๋ฝ์ ํ๋ํ ๋๊น์ง ๋๊ธฐํ๋ฉฐ, ์ด ๋์ CPU ์คํ ์ค์ผ์ค๋ง์์ ์ ์ธ๋ฉ๋๋ค.
- ์ฌ๋ฌ ์ค๋ ๋๊ฐ ๋๊ธฐ ์ค์ผ ๊ฒฝ์ฐ, ๋ฝ ํ๋ ์์๋ ๋ณด์ฅ๋์ง ์์ต๋๋ค.
- synchronized ๋ธ๋ก ์์์๋ ๋ณ์์ ๋ฉ๋ชจ๋ฆฌ ๊ฐ์์ฑ ๋ฌธ์ ๊ฐ ์๋์ผ๋ก ํด๊ฒฐ๋๋ฏ๋ก, ๋ณ๋์ volatile ์ ์ธ์ด ํ์ํ์ง ์์ต๋๋ค.
synchronized ๋จ์ 2๊ฐ์ง
- ๋ฌดํ ๋๊ธฐ : BLOCKED ์ํ์ ์ค๋ ๋๋ ๋ฝ์ด ํ๋ฆด ๋๊น์ง ๋ฌดํ ๋๊ธฐ๋ก ์ธํฐ๋ฝํธ, ํ์์์ ์ ์ฉ์ด ์๋ฉ๋๋ค.
- ๊ณต์ ์ฑ ๋ฌธ์ : ๋ฝ์ด ๋์์์ ๋, BLOCKED ์ํ์ ์ฌ๋ฌ ์ค๋ ๋ ์ค์ ์ด๋ค ์ค๋ ๋๊ฐ ๋ฝ์ ํ๋ํ ์ง ์์ ์์ต๋๋ค.
BLOCKED ๋ ์ค๋ ๋์ ์ํ ์ค ์ผ๋ถ๋ก ์ค๋ ๋์ ์ํ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
NEW | ์ค๋ ๋๊ฐ ์์ฑ๋์์ง๋ง ์์ง ์์๋์ง ์์ ์ํ. Thread thread = new Thread(runnable) |
RUNNABLE | ์คํ ์ค์ด๊ฑฐ๋ ์คํ ์ค๋น๊ฐ ์๋ฃ๋ ์ํ. thread.start() |
BLOCKED | ๋๊ธฐํ ๋ฝ์ ๊ธฐ๋ค๋ฆฌ๋ ์ํ. (synchronized ์ฌ์ฉ ์ ๋ฐ์) synchronized (lock) {…} |
WAITING | ๋ค๋ฅธ ์ค๋ ๋์ ํน์ ์์ ์ด ์๋ฃ๋๊ธฐ๋ฅผ ๋ฌดํ์ ๊ธฐ๋ค๋ฆฌ๋ ์ํ. (wait(), join() ํธ์ถ ์) |
TIMED_WAITING | ํน์ ์๊ฐ ๋์ ๋๊ธฐํ๋ ์ํ. (sleep(), wait(timeout), join(timeout) ํธ์ถ ์) |
TERMINATED | ์ค๋ ๋์ ์คํ์ด ์๋ฃ๋ ์ํ. |
BLOCKED & WAITING ์ ๋ชจ๋ ์ค๋ ๋๊ฐ ๋๊ธฐํ๋ฉฐ CPU ์คํ ์ค์ผ์ค๋ง์ ๋ค์ด๊ฐ์ง ์๊ธฐ ๋๋ฌธ์, CPU์์ ๋ณด๋ฉด ์คํํ์ง ์๋ ๋น์ทํ ์ํ์ด์ง๋ง ํฐ ์ฐจ์ด๊ฐ ์์ต๋๋ค.
BLOCKED → ์ธํฐ๋ฝํธ๊ฐ ๊ฑธ๋ ค๋ ์ฌ์ ํ BLOCKED
- synchronized ์์ ๋ฝ์ ํ๋ํ๊ธฐ ์ํด ๋๊ธฐํ ๋ ์ฌ์ฉํ๋ ํน๋ณํ ์ํ์ ๋๋ค.
WAITING(TIME_WAITING) → ์ธํฐ๋ฝํธ๊ฐ ๊ฑธ๋ฆฌ๋ฉด RUNNABLE ๋ณ๊ฒฝ
- ์ค๋ ๋๊ฐ ํน์ ์กฐ๊ฑด์ด๋ ์๊ฐ ๋์ ๋๊ธฐํ ๋ ๋ฐ์ํ๋ ์ํ์ ๋๋ค.
2. synchronized vs static synchronized
synchronized ํค์๋๊ฐ ์ธ์คํด์ค๋ณ๋ก ์๋ํ๋์ง, static synchronized๊ฐ ํด๋์ค ๋ ๋ฒจ์์ ์๋ํ๋์ง ์คํ์ ํตํด ํ์ธํด๋ณด๊ฒ ์ต๋๋ค.
์คํ 1, synchronized ๋ฉ์๋์ ๋์ ํ์ธ
์คํ ์ฝ๋
public class SyncMain {
public static void main(String[] args) {
MyTask task1 = new MyTask();
Thread thread1 = new Thread(task1, "thread1");
thread1.start();
Thread thread2 = new Thread(task1, "thread2");
thread2.start();
}
static class MyTask implements Runnable {
Logger logger = new Logger();
@Override
public void run() {
String name = Thread.currentThread().getName();
while (true) {
logger.logging(name);
sleep(1000);
}
}
}
}
public class Logger {
public synchronized void logging(String threadName) {
while (true) {
System.out.println("logging: " + threadName);
sleep(1000);
}
}
}
์คํ ๋ชฉ์ : ๋์ผ ์ธ์คํด์ค์ synchronized ๋ฉ์๋๋ฅผ ์ฌ๋ฌ ์ค๋ ๋์์ ํธ์ถํ ๊ฒฝ์ฐ ๋๊ธฐํ๊ฐ ์ด๋ฃจ์ด์ง๋์ง ํ์ธํฉ๋๋ค.
์์ ๊ฒฐ๊ณผ: ํ ์ค๋ ๋๊ฐ logging ๋ฉ์๋(์๊ณ์์ญ)์ ์ง์ ํ๋ฉด, ๋ค๋ฅธ ์ค๋ ๋๋ BLOCKED ์ํ๊ฐ ๋์ด ๋ก๊ทธ๋ฅผ ๋จ๊ธธ ์ ์์ต๋๋ค.
๊ฒฐ๊ณผ: ํ ์ค๋ ๋์ ๋ก๊ทธ๋ง ์ถ๋ ฅ๋ฉ๋๋ค. ๋๊ธฐํ๊ฐ ์ ์์ ์ผ๋ก ์ด๋ฃจ์ด์ก์์ ํ์ธํ์ต๋๋ค.
์คํ 2, synchronized์ ์ธ์คํด์ค๋ณ ๋ฝ ํ์ธ
์คํ ์ฝ๋
MyTask task1 = new MyTask();
MyTask task2 = new MyTask();
Thread thread1 = new Thread(task1, "thread1");
thread1.start();
Thread thread2 = new Thread(task2, "thread2");
thread2.start();
์คํ ๋ชฉ์ : ๊ฐ๊ธฐ ๋ค๋ฅธ ์ธ์คํด์ค๊ฐ ์๋ก ๋ ๋ฆฝ์ ์ธ ๋ชจ๋ํฐ ๋ฝ์ ๊ฐ์ง๋์ง ํ์ธํฉ๋๋ค.
์์ ๊ฒฐ๊ณผ
- ๊ฐ ์ธ์คํด์ค๋ ์์ ๋ง์ ๋ชจ๋ํฐ ๋ฝ์ ๊ฐ์ง๊ณ ์์ต๋๋ค.
- ๋ ์ค๋ ๋๋ ์๋ก ๋ค๋ฅธ ์ธ์คํด์ค์ logging ๋ฉ์๋๋ฅผ ์คํํ๋ฏ๋ก ๊ฐ๊ฐ ๋ก๊ทธ๋ฅผ ๋จ๊ธธ ์ ์์ต๋๋ค.
๊ฒฐ๊ณผ: ์ค๋ ๋๋ณ๋ก ๋ก๊ทธ๊ฐ ์ถ๋ ฅ๋ฉ๋๋ค. ์ด๋ ๊ฐ ์ธ์คํด์ค๊ฐ ๊ณ ์ ํ ๋ชจ๋ํฐ ๋ฝ์ ๊ฐ์ง๊ณ ์์์ ์๋ฏธํฉ๋๋ค.
์คํ 3, static synchronized์ ํด๋์ค ๋ ๋ฒจ ๋ฝ ํ์ธ
์คํ ์ฝ๋
public class SyncMain {
public static void main(String[] args) {
MyTask task1 = new MyTask();
MyTask task2 = new MyTask();
Thread thread1 = new Thread(task1, "thread1");
thread1.start();
Thread thread2 = new Thread(task2, "thread2");
thread2.start();
}
static class MyTask implements Runnable {
@Override
public void run() {
String name = Thread.currentThread().getName();
while (true) {
Logger.logging(name);
sleep(1000);
}
}
}
}
public class Logger {
public static synchronized void logging(String threadName) {
while (true) {
System.out.println("logging: " + threadName);
sleep(1000);
}
}
}
์คํ ๋ชฉ์ : static synchronized ๋ฉ์๋๊ฐ ์ฌ๋ฌ ์ธ์คํด์ค์์๋ ํด๋์ค ๋ ๋ฒจ์ ๋ฝ์ ๊ณต์ ํ๋์ง ํ์ธํฉ๋๋ค.
์์ ๊ฒฐ๊ณผ
- ์๋ก ๋ค๋ฅธ MyTask ์ธ์คํด์ค๋ฅผ ์์ฑํ์ง๋ง, static synchronized ํค์๋๋ก ์ธํด ํด๋์ค ๋ ๋ฒจ์ ๋ฝ์ ๊ณต์ ํฉ๋๋ค.
- ํ ์ค๋ ๋๊ฐ ๋ฝ์ ์์ ํ ๋์, ๋ค๋ฅธ ์ค๋ ๋๋ BLOCKED ์ํ๊ฐ ๋์ด ๋ก๊ทธ๋ฅผ ๋จ๊ธธ ์ ์์ต๋๋ค.
๊ฒฐ๊ณผ: ํ ์ค๋ ๋๋ง ๋ก๊ทธ๋ฅผ ๋จ๊น๋๋ค. ํด๋์ค ๋ ๋ฒจ์ ๋ฝ์ด ๊ณต์ ๋๊ณ ์์์ ํ์ธํ์ต๋๋ค.
๊ฒฐ๋ก
synchronized ํค์๋๋ ์ธ์คํด์ค๋ง๋ค ๊ณ ์ ํ ๋ชจ๋ํฐ ๋ฝ์ ์ฌ์ฉํฉ๋๋ค.
- ๋์ผ ์ธ์คํด์ค์์ ๋๊ธฐํ๋ ๋ฉ์๋๋ฅผ ํธ์ถํ ๊ฒฝ์ฐ, ์ค๋ ๋๋ ๋ฝ์ ์ป๊ธฐ ์ํด BLOCKED ์ํ๋ก ๋๊ธฐํฉ๋๋ค.
static synchronized ํค์๋๋ ํด๋์ค ๋ ๋ฒจ์ ๋ชจ๋ํฐ ๋ฝ์ ์ฌ์ฉํฉ๋๋ค.
- ์๋ก ๋ค๋ฅธ ์ธ์คํด์ค๋ผ๋ ๋์ผํ ๋ฝ์ ๊ณต์ ํ์ฌ, ํ ์ค๋ ๋๊ฐ ๋ฝ์ ์ ์ ํ๋ฉด ๋ค๋ฅธ ์ค๋ ๋๋ ๋๊ธฐํด์ผ ํฉ๋๋ค.
3. synchronized ๋จ์ ์ ๊ทน๋ณตํ ReentrantLock ์๊ฐ
synchronized ํค์๋๋ ๋๊ธฐํ๋ฅผ ์ ๊ณตํ์ง๋ง, ๋ฌดํ ๋๊ธฐ์ ๋น๊ณต์ ์ฑ์ด๋ผ๋ ๋จ์ ์ด ์์ต๋๋ค.
์ด๋ฌํ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด Java 5๋ถํฐ ReentrantLock์ด ๋์ ๋์์ต๋๋ค. ReentrantLock์ LockSupport๋ฅผ ํ์ฉํ์ฌ ์ ๋จ์ ์ ๊ทน๋ณตํฉ๋๋ค.
1. ๋ฌดํ ๋๊ธฐ ๊ทน๋ณต
LockSupport๋ concurrent ํจํค์ง์ ์์นํ๋ฉฐ, ์ ์์ค์ ๊ฐ์ฒด์ ๋๋ค. LockSupport๋ ์ค๋ ๋๊ฐ ๋ฝ์ ํ๋ํ๋ ค๊ณ ๋๊ธฐํ ๋, ์ค๋ ๋์ ์ํ๋ฅผ BLOCKED ๋์ WAITING์ผ๋ก ๋ณ๊ฒฝํด์ ์ธํฐ๋ฝํธ๋ฅผ ํ์ฉํ๊ฒ ํด์ค๋๋ค. ์ด๋ฅผ ํตํด synchronized์ ๋ฌดํ ๋๊ธฐ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํฉ๋๋ค.
2. ๊ณต์ ์ฑ ๊ทน๋ณต
ReentrantLock์ ๊ณต์ ๋ชจ๋์ ๋น๊ณต์ ๋ชจ๋๋ฅผ ์ ๊ณตํ๋ฉฐ, ํ์์ ๋ฐ๋ผ ์ ํํ ์ ์์ต๋๋ค.
2-1. ๊ณต์ ๋ชจ๋ (Fair Mode)
ํน์ง
- ๋๊ธฐ ํ์ ์๋ ์ค๋ ๋๊ฐ ๋ฝ์ ์์ฒญํ ์์๋๋ก ๋ฝ์ ํ๋ํฉ๋๋ค
- ๋ชจ๋ ์ค๋ ๋๊ฐ ์ธ์ ๊ฐ๋ ๋ฝ์ ํ๋ํ ์ ์์ต๋๋ค.(๊ธฐ์ ํ์ ๋ฐฉ์ง)
๋จ์
- ๋๊ธฐ ํ ๊ด๋ฆฌ๋ก ์ธํด ์ฑ๋ฅ์ด ์ ํ๋ ์ ์์ต๋๋ค.
์ฌ์ฉ ๋ฐฉ๋ฒ
Lock lock = new ReentrantLock(true); // ๊ณต์ ๋ชจ๋ ์ค์
2-2. ๋น๊ณต์ ๋ชจ๋ (Non-Fair Mode)
ํน์ง
- ์ฑ๋ฅ์ ์ค์ํ๋ ํ๊ฒฝ์์ ์ฌ์ฉ๋ฉ๋๋ค.
- ๋น๊ณต์ ๋ชจ๋์ด์ง๋ง, ReentrantLock์ ๋ด๋ถ์ ์ผ๋ก ํ๋ก ๊ตฌํ๋์ด์๊ธฐ ๋๋ฌธ์ ์ค๋ ๋ ๊ฐ ๊ฒฝํฉ์ด ํฌ์ง ์๋ ์ด์ ์์๋๋ก ์ฒ๋ฆฌ๋ฉ๋๋ค.
์ฌ์ฉ ๋ฐฉ๋ฒ
Lock lock = new ReentrantLock(); // ๊ธฐ๋ณธ์ ๋น๊ณต์ ๋ชจ๋
ReentrantLock์ ๊ธฐ๋ณธ ์ฌ์ฉ๋ฒ
ReentrantLock์ ์๊ณ์์ญ์ ๋ํด ๋ช
์์ ์ผ๋ก lock()๊ณผ unlock()์ ํธ์ถํฉ๋๋ค.
unlock()์ ๋ฐ๋์ finally ๋ธ๋ก์์ ํธ์ถํ์ฌ, ๋ฝ์ด ํญ์ ํด์ ๋๋๋ก ๋ณด์ฅํด์ผ ํฉ๋๋ค.
Lock lock = new ReentrantLock();
try {
lock.lock(); // ๋ฝ ํ๋
// ์๊ณ์์ญ
} finally {
lock.unlock(); // ๋ฝ ํด์
}
ReentrantLock์ Lock ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ ๋ํ์ ์ธ ํด๋์ค์ ๋๋ค. ์ด ์ธํฐํ์ด์ค๊ฐ ์ ๊ณตํ๋ ์ฃผ์ ๋ฉ์๋๋ฅผ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
void lock()
- ๋ฝ์ ํ๋ํ๋ค. ๋ง์ฝ, ๋ค๋ฅธ ์ค๋ ๋๊ฐ ์ด๋ฏธ ๋ฝ์ ํ๋ ํ๋ค๋ฉด ๋ฝ์ด ํ๋ฆด ๋๊น์ง ํ์ฌ ์ค๋ ๋๋ WAITING ์ํ๊ฐ ๋๋ค. ํ์ง๋ง ์ธํฐ๋ฝํธ์ ์๋ตํ์ง ์๋๋ค.
- WAITING ์ํ์ง๋ง ์ ์ธํฐ๋ฝํธ์ ์๋ตํ์ง ์๋ ์ด์ ?
- ๋ด๋ถ ๊ตฌํ์์ ์ธํฐ๋ฝํธ๊ฐ ๋ฐ์ํ๋ฉด ์๊ฐ WAITING ์ํ๋ฅผ ๋น ์ ธ๋์์ RUNNABLE ์ํ๊ฐ ๋์ง๋ง, ๋ค์ ํด๋น ์ค๋ ๋๋ฅผ WAITING ์ํ๋ก ๊ฐ์ ๋ก ๋ณ๊ฒฝํด๋ฒ๋ฆฐ๋ค.
- ์ด ๋ฝ์ ๋ชจ๋ํฐ ๋ฝ์ด ์๋๊ณ , Lock ์ธํฐํ์ด์ค์ ReentrantLock ์ด ์ ๊ณตํ๋ ๊ธฐ๋ฅ์ด๋ฉฐ, ๋ชจ๋ํฐ ๋ฝ๊ณผ BLOCKED ์ํ๋ synchronized ์์๋ง ์ฌ์ฉ๋๋ค.
void lockInterruptibly()
- ๋ฝ ํ๋์ ์๋ํ๋, ๋ค๋ฅธ ์ค๋ ๋๊ฐ ์ธํฐ๋ฝํธ๋ฅผ ๋ฐ์์์ผ WAITING ์ํ์์ ๋ฒ์ด๋์ ๋ฝ ํ๋์ ํฌ๊ธฐ ํ ์ ์๋ค.
boolean tryLock()
- ๋ฝ ํ๋์ ์๋ํ๊ณ , ์ฆ์ ์ฑ๊ณต ์ฌ๋ถ๋ฅผ ๋ฐํ. ๋ฝ์ ํ๋ํ๋ฉด true, ์๋๋ฉด false
boolean tryLock(long time, TimeUnit unit)
- ์ฃผ์ด์ง ์๊ฐ ์์ ๋ฝ์ ํ๋ํ๋ฉด true ๋ฅผ ๋ฐํ, ์ฃผ์ด์ง ์๊ฐ ์์ ๋ฝ ํ๋ ๋ชปํ๋ฉด false ๋ฐํ. ๋ฝ ํ๋ ๋๊ธฐ ์ค ์ธํฐ๋ฝํธ๊ฐ ๋ฐ์ํ๋ฉด ๋ฝ ํ๋์ ํฌ๊ธฐํ๋ค.
void unlock()
- ๋ฝ์ ํ๋ํ ์ค๋ ๋๊ฐ ํธ์ถํด์ผ ํ๋ฉฐ, ๋ฝ์ ํด์ ํ๋ค.
Condition newCondition()
- Condition ๊ฐ์ฒด๋ ๋ฝ๊ณผ ๊ฒฐํฉ๋์ด ์ฌ์ฉ๋๋ฉฐ, ์ค๋ ๋๊ฐ ํน์ ์กฐ๊ฑด์ ๊ธฐ๋ค๋ฆฌ๊ฑฐ๋ ์ ํธ๋ฅผ ๋ฐ๋๋ค. Object ํด๋์ค์ wait, notify ๋ฉ์๋์ ์ ์ฌํ ์ญํ ์ ํ๋ค.
4. synchronized vs ReentrantLock
synchronized์ ReentrantLock์ ๋ชจ๋ ๋๊ธฐํ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์๋ ๊ธฐ๋ฒ์ ๋๋ค.
ํ์ง๋ง ๋ ์ฌ์ด์๋ ๋ช ๊ฐ์ง ์ค์ํ ์ฐจ์ด์ ์ด ์์ต๋๋ค.
1. ์ ๊ณต ๋ฐฉ์
- synchronized๋ ์๋ฐ ์ธ์ด ์ฐจ์์์ ์ ๊ณตํ๋ ํค์๋๋ก ๋ชจ๋ ์ธ์คํด์ค์๋ ๋ชจ๋ํฐ ๋ฝ์ด ์์ต๋๋ค.(wait set ํฌํจ)
- ReentrantLock์ Java์ java.util.concurrent ๋ผ์ด๋ธ๋ฌ๋ฆฌ์์ ์ ๊ณตํ๋ ํด๋์ค์ ๋๋ค. ์ฝ๋์ ์ผ๋ก ์ง์ํฉ๋๋ค.
2. ์ค๋ ๋ ๋๊ธฐ ์ํ
- synchronized๋ฅผ ์ฌ์ฉํ ๋, ์ค๋ ๋๊ฐ ๋ฝ์ ๊ธฐ๋ค๋ฆฌ๋ ์ํ๋ BLOCKED์ ๋๋ค. ์ด ์ํ์์๋ ์ธํฐ๋ฝํธ๋ฅผ ํตํด ์ค๋ ๋๋ฅผ ๊นจ์ธ ์ ์์ต๋๋ค.
- ๋ฐ๋ฉด, ReentrantLock์ ์ฌ์ฉํ ๊ฒฝ์ฐ, ์ค๋ ๋๊ฐ ๋ฝ์ ๊ธฐ๋ค๋ฆฌ๋ ์ํ๋ WAITING ๋๋ TIMED_WAITING์ผ๋ก, ์ธํฐ๋ฝํธ๋ฅผ ํตํด ๋๊ธฐ๋ฅผ ์ค๋จํ ์ ์์ต๋๋ค.
3. ์์ฐ์-์๋น์ ๋ฌธ์ , ํ์ ๋ ๋ฒํผ ๋ฌธ์ ์์์ ํจ์จ์ฑ
- synchronized๋ฅผ ์ฌ์ฉํ ๊ฒฝ์ฐ, ๋๊ธฐ ์งํฉ(wait set)์์ ์ํ๋ ์ค๋ ๋๋ง ์ ํ์ ์ผ๋ก ๊นจ์ธ ์ ์์ด์ ๋นํจ์จ์ ์ ๋๋ค.(๋นํจ์จ์ ์ด์ง ์์ฐ์-์๋น์ ๋ฌธ์ ์ ํ์ ๋ ๋ฒํผ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์๋ ์์ต๋๋ค.)
- ReentrantLock์ Condition ๊ฐ์ฒด๋ฅผ ํ์ฉํ์ฌ ์ํ๋ ์ค๋ ๋๋ง ์ ํ์ ์ผ๋ก ๊นจ์ธ ์ ์์ด ์์ฐ์-์๋น์ ๋ฌธ์ ๋ฅผ ํจ์จ์ ์ผ๋ก ํด๊ฒฐํ ์ ์์ต๋๋ค.
* ์์ฐ์-์๋น์ ๋ฌธ์ ์ ๋ํด synchronized ์ ReentrantLock ์ฐจ์ด๋ฅผ ๋ ์์ธํ ์๊ณ ์ถ๋ค๋ฉด ๊น์ํ๋์ ๊ณ ๊ธ ์๋ฐ ๊ฐ์๋ฅผ ์ถ์ฒ๋๋ฆฝ๋๋ค.
๋ง์น๋ฉฐ..
์ด๋ฒ ๊ธ์์๋ synchronized์ ReentrantLock์ ๋ํด ์์๋ณด์์ต๋๋ค.
๊ทธ๋์ Async์ Sync์ ์ฐจ์ด, Non-Blocking๊ณผ Blocking์ ์ฐจ์ด๋ฅผ ์ดํดํ๊ธฐ์ ๋ฉํฐ์ค๋ ๋๋ฅผ ์ถฉ๋ถํ ์ดํดํ๋ค๊ณ ์๊ฐํ๋ ์ ์์ ์ ๋์๋ณด๊ฒ ๋์์ต๋๋ค. ์ด๋ฒ ํ์ต์ ํตํด Java๋ ์ ์ด์ ๋ฉํฐ์ค๋ ๋๋ฅผ ์ผ๋์ ๋๊ณ ์ค๊ณ๋ ์ธ์ด์ด๋ฉฐ, ์ด๋ฅผ ์ง์ํ๊ธฐ ์ํ ๋ค์ํ ๋๊ธฐํ ๋ฐฉ๋ฒ์ ์ ๊ณตํ๋ค๋ ์ ์ ์๋กญ๊ฒ ๊นจ๋ฌ์์ต๋๋ค.
์ด ๊ธ์ ์์ฑํ๋ฉฐ synchronized ๋ ์ค๋ ๋ ๊ฐ ๋ฐ์ดํฐ ์ ๋ฌ์ด ํ์ ์๋ ๊ฐ๋จํ ๋๊ธฐํ์์ ์ฌ์ฉํ ์ ์์ ๊ฒ ๊ฐ๊ณ , ReentrantLock ์ concurrent ํจํค์ง์ ์๋ BlockingQueue์ ๋ด๋ถ ๊ตฌํ์ ์ฌ์ฉ๋ฉ๋๋ค. ๊ทธ๋ฌ๋, BlockingQueue ๋ ์ค๋ ๋ ๊ฐ์ ๋ฐ์ดํฐ ์ ๋ฌํ๋ ์ํฉ(์์ฐ์-์๋น์ ๋ฌธ์ ๊ฐ์ด)์ ์ฌ์ฉํ๊ธฐ์ ์ ํฉํ๋ค๋ ์๊ฐ์ด ๋ญ๋๋ค.
์ฝ์ด์ฃผ์ ์ ๊ฐ์ฌํฉ๋๋ค.
์ถ์ฒ
- ๊น์ํ๋์ ๊ณ ๊ธ ์๋ฐ ๊ฐ์