์ค๋์ ๋ฝ(Lock)์ ๋ํด์ ์กฐ๊ธ ๊ณต๋ถํด๋ณด๋ ค๊ณ ํ๋ค. ์๋ฐ์์ ๋ฉํฐ์ค๋ ๋ ํ๊ฒฝ์ ๋ค๋ฃจ๋ค ๋ณด๋ฉด, ์ฌ๋ฌ ์ค๋ ๋๊ฐ ๋์์ ๊ฐ์ ์์์ ์ ๊ทผํ ๋ ๋ฌธ์ ๊ฐ ์๊ธธ ์ ์๋๋ฐ, ์ด๋ฐ ๊ฑธ ๋ง๊ธฐ ์ํด ๋ฝ์ ์ฌ์ฉํ๋ค. ์ด๋ฒ์๋ ํนํ ReentrantLock๊ณผ ReentrantReadWriteLock์ด ์ด๋ป๊ฒ ๋์ํ๋์ง, ๊ทธ๋ฆฌ๊ณ ์ธ์ ์ฐ๋ฉด ์ข์์ง ์ดํด๋ณผ ์์ ์ด๋ค. ์์ง๊น์ง ๋ฝ(Lock)๊ณผ ๋์์ฑ์ ๋ํํ ๋๋ฌด ์ด๋ ต๋ค...
์ ์ฐ๋ฆฌ๋ ๋ฝ(Lock)์ ์ฌ์ฉํ๋ ๊ฑธ๊น? ์์งํ๊ฒ ๋๋ ๋ฝ(Lock)์ ๋ํด ์ ์ง ์ผ๋ง ๋์ง ์์๋ค.
๊ทธ๋ฐ๋ฐ ๋ฉํฐ์ค๋ ๋ ํ๊ฒฝ์์ ์ฌ๋ฌ ์ค๋ ๋๊ฐ ๋์์ ๊ฐ์ ์์์ ์ ๊ทผํ๋ฉด, ๊ฐ์ด ๊ผฌ์ด๊ฑฐ๋ ์์๊ณผ ๋ค๋ฅธ ๊ฒฐ๊ณผ๊ฐ ๋์ค๋ ๊ฒฝ์ฐ๊ฐ ์๊ธด๋ค๋ ๊ฑธ ์๊ฒ ๋์๋ค. ๊ทธ๋์ ์ด๋ฐ ๋ฌธ์ ๋ฅผ ๋ง๊ณ , ์์ ํ๊ฒ ๊ณต์ ์์์ ๋ค๋ฃจ๊ธฐ ์ํด ๋ฝ์ด ํ์ํ๋ค๋ ๊ฒ์ ๋ฐฐ์ฐ๊ฒ ๋ ๊ฒ์ด๋ค.
์ผ๋จ ๋ฝ(Lock)์ ์ฌ์ฉํ์ง ์์ผ๋ฉด ์ด๋ป๊ฒ ๋๋์ง ์ฝ๋๋ก ํ์ธํด๋ณด์
public class NoLockExample {
static int count = 0;
public static void main(String[] args) {
Thread a = new Thread(addCount("A "));
Thread b = new Thread(addCount("B "));
Thread c = new Thread(addCount("C "));
Thread d = new Thread(addCount("D "));
Thread e = new Thread(addCount("E "));
a.start();
b.start();
c.start();
d.start();
e.start();
}
static Runnable addCount(String threadName) {
return () -> IntStream.range(0, 20000).forEach(i -> {
System.out.println(threadName + count++);
});
}
}

์ฐ๋ฆฌ๋ 5๊ฐ์ ์ค๋ ๋๊ฐ ๊ฐ๊ฐ 20,000๋ฒ์ฉ count๋ฅผ ์ฆ๊ฐ์ํค๋๊น, ์ต์ข ์ ์ผ๋ก 99999๊น์ง ์ฆ๊ฐํ ๊ฒ์ ์์ํ๋ค.
ํ์ง๋ง ์ค์ ๋ก ์ฝ๋๋ฅผ ์คํํ๋ฉด, ๊ฒฐ๊ณผ๋ 99,989๊น์ง๋ง ์ฆ๊ฐํ๋ ๋ฑ ์์๊ณผ ๋ฌ๋ฆฌ ๊ฐ์ด ๋๋ฝ๋๋ ํ์์ ํ์ธํ ์ ์๋ค.
๊ทธ ์ด์ ๋ count++ ์ฐ์ฐ์ด ์ฝ๊ธฐ โ ๋ํ๊ธฐ โ ์ ์ฅ์ 3๋จ๊ณ๋ก ์ด๋ฃจ์ด์ ธ ์๊ณ , ์ฌ๋ฌ ์ค๋ ๋๊ฐ ๋์์ ์ ๊ทผํ๋ฉด ์๋ก ๋ฎ์ด์ฐ๊ธฐ๊ฐ ๋ฐ์ํ๊ธฐ ๋๋ฌธ์ด๋ค.
์ฆ, ๋ฝ์ ๊ฑธ์ง ์์ผ๋ฉด ์ค๋ ๋ ๊ฐ ๊ฐ์ญ์ผ๋ก ์ธํด ๊ฐ์ด ๊ผฌ์ด๋ ๋ฌธ์ (race condition)๊ฐ ๋ฐ์ํ๊ฒ ๋๋ค.
๋ฌผ๋ก ๊ฐ๋จํ๊ฒ ์์ ์ ์ ๋ฆฌํ๋ synchronized ํค์๋๋ฅผ ์ฌ์ฉํ์ฌ ์ด๋ฅผ ํด๊ฒฐํ ์ ์๋ค.
public class LockExample {
static int count = 0;
public static void main(String[] args) {
Thread a = new Thread(addCount("A "));
Thread b = new Thread(addCount("B "));
Thread c = new Thread(addCount("C "));
Thread d = new Thread(addCount("D "));
Thread e = new Thread(addCount("E "));
a.start();
b.start();
c.start();
d.start();
e.start();
}
static Runnable addCount(String threadName) {
return () -> IntStream.range(0, 20000).forEach(i -> {
incrementCount(threadName);
});
}
static synchronized void incrementCount(String threadName) {
System.out.println(threadName + count++);
}
}

ํ์ง๋ง synchronized๋ thread-Safeํ ์์ ์ด ๊ฐ๋ฅํ์ง๋ง ์ฑ๋ฅ ์ ํ๊ฐ ์๊ธฐ๊ธฐ ์ฝ๊ณ , ์ธ๋ฐํ ์ ์ด๊ฐ ์ด๋ ต๊ณ , ์ฝ๊ธฐ/์ฐ๊ธฐ ๊ตฌ๋ถ์ด ์ ๋์ด ๋ณ๋ ฌ ์ฒ๋ฆฌ ํจ์จ์ด ๋จ์ด์ง๋ค.
์ด๋ฐ ๋จ์ ์ ํด๊ฒฐํ๊ธฐ ์ํด ๋์จ ๊ฒ์ด ReentrantLock๊ณผ ReentrantReadWriteLock ์ด๋ค.
void lock() // lock ์ ๊ธ
void unlock() // lock ํด์
boolean isLocked() // lock์ด ์ ๊ฒผ๋์ง ํ์ธ
boolean tryLock() // lock polling
boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException
์๋์ผ๋ก ๋ฝ์ ๊ฑธ๊ณ (lock()), ํ ์(unlock()) ์๋ ๊ฐ์ฒด
์ฆ, ์ ๊ธ ์์ญ์ ์์๊ณผ ๋์ ๊ฐ๋ฐ์๊ฐ ์ง์ ์ ์ดํ ์ ์๋ค๋ ๋ป์ด๋ค.
ReentrantLock์ ์ด๋ฆ ๊ทธ๋๋ก ์ฌ์ง์ ๊ฐ๋ฅ(Reentrant) โ ๊ฐ์ ์ค๋ ๋๊ฐ ์ด๋ฏธ ํ๋ํ ๋ฝ์ ๋ค์ ํ๋ํ ์ ์์
tryLock(), ๊ณต์ ์ฑ ์ต์ (fairness) ๋ฑ synchronized๋ณด๋ค ์ ์ฐํ ๊ธฐ๋ฅ ์ ๊ณตํ๋ค.
์ฝ๋๋ก ํ์ธํด๋ณด์!!
public class LockExample {
static int count = 0;
static ReentrantLock lock = new ReentrantLock();
public static void main(String[] args) {
Thread a = new Thread(addCount("A "));
Thread b = new Thread(addCount("B "));
Thread c = new Thread(addCount("C "));
Thread d = new Thread(addCount("D "));
Thread e = new Thread(addCount("E "));
a.start();
b.start();
c.start();
d.start();
e.start();
}
static Runnable addCount(String threadName) {
return () -> IntStream.range(0, 20000).forEach(i -> {
incrementCount(threadName);
});
}
static void incrementCount(String threadName) {
lock.lock(); // ๋ฝ ํ๋
try {
System.out.println(threadName + count++);
} finally {
lock.unlock(); // ๋ฐ๋์ ๋ฝ ํด์
}
}
}

์ญ์ ์์๋๋ก 99999 ๊ฐ ๋์ค๋ ๊ฒ์ ํ์ธ ํ ์ ์๋ค.
๊ทธ๋ฐ๋ฐ ๋ฉํฐ์ค๋ ๋ ํ๊ฒฝ์์ ๋ฝ(Lock)์ ๊ฐ์ง ์ฑ ์ค๋ซ๋์ ์์ ์ ํ๋ ์ค๋ ๋๊ฐ ์์ผ๋ฉด, ๋ค๋ฅธ ์ค๋ ๋๋ค์ ๊ทธ ๋ฝ์ ๋ชป ์ป์ด์ ๊ธฐ๋ค๋ ค์ผ ํ๋ค.
๊ทธ๋์ ๊ณต์ ๋ฐ์ดํฐ๋ฅผ ๋ณดํธํ๋ ๊ฒ๋งํผ, ๋ฝ์ ์ค๋ ์ก๊ณ ์์ง ์๊ฒ ํ๋ ๊ฒ๋ ์ค์ํ๋ค.
์๋ฐ์์๋ ์ด๋ฐ ์ํฉ์ ์ ์ดํ๊ธฐ ์ํด wait(), notify(), notifyAll() ๊ฐ์ ๋ฉ์๋๋ฅผ ์ ๊ณตํ๋ค.
์คํ ์ค์ธ ์ค๋ ๋๊ฐ ๋ฝ์ ๋ฐ๋ฉํ๊ณ ๋๊ธฐ ์ํ๋ก ๋ค์ด๊ฐ๊ฒ ํ๋ค.
waiting pool์ด๋ผ๋ ๊ณณ์์ ๋ค๋ฅธ ์ค๋ ๋๊ฐ ๋ฝ์ ์ฌ์ฉํ ์ ์๋๋ก ๊ธฐ๋ค๋ฆผ
๋ฝ์ ์ก์ ์ํ์์ ์ค๋ซ๋์ ๋ฉ์ถฐ์๋ ๊ฑธ ๋ฐฉ์งํ๋ค.
waiting pool์ ์๋ ํ๋์ ์ค๋ ๋์๊ฒ ์์ ์ ๊ณ์ํ ์ ์๋ค๊ณ ์๋ฆผ
์ด๋ค ์ค๋ ๋๊ฐ ๋ฝ์ ์ป์์ง๋ ๋ณด์ฅ ๋ชปํจ โ JVM ์ค์ผ์ค๋ฌ๊ฐ ๊ฒฐ์
waiting pool์ ์๋ ๋ชจ๋ ์ค๋ ๋์๊ฒ ์๋ฆผ
๋จ, ๋ฝ์ ํ ๋ฒ์ ํ๋์ ์ค๋ ๋๋ง ํ๋ ๊ฐ๋ฅ โ ๋๋จธ์ง๋ ๋ฝ์ ์ป๊ธฐ ์ํด ๋ค์ ๊ธฐ๋ค๋ฆผ
| synchronized / Object | ReentrantLock / Condition | ์ค๋ช |
|---|---|---|
synchronized | lock() / unlock() | ๋ฝ์ ํ๋ํ๊ณ ํด์ . synchronized๋ ๋ธ๋ก ๋จ์, ReentrantLock์ ์๋ ์ ์ด |
wait() | await() | ๋ฝ์ ๋ฐ๋ฉํ๊ณ ๋๊ธฐ. Condition ๊ฐ์ฒด๋ฅผ ํตํด ๊ธฐ๋ค๋ฆผ |
notify() | signal() | waiting pool์ ์๋ ํ๋์ ์ค๋ ๋๋ฅผ ๊นจ์์ ๋ฝ์ ๋ค์ ์ป์ด ์์ ์งํ |
notifyAll() | signalAll() | waiting pool์ ์๋ ๋ชจ๋ ์ค๋ ๋์๊ฒ ์๋ฆผ, ๋ฝ์ ํ ๋ฒ์ ํ๋์ฉ๋ง ์ป์ ์ ์์ |
๐ค Condition์ Lock๊ณผ ํจ๊ป ์ฌ์ฉ๋๋ฉฐ,
ํน์ ์กฐ๊ฑด์ด ๋ง์กฑ๋ ๋๊น์ง ์ค๋ ๋๋ฅผ ๋๊ธฐ(wait) ์ํค๊ฑฐ๋, ์กฐ๊ฑด์ด ๋ง์กฑ๋๋ฉด ๋๊ธฐ ์ค์ธ ์ค๋ ๋๋ฅผ ๊นจ์ฐ๋(signal) ์ญํ ์ ํ๋ค.
- ์ฆ, "์กฐ๊ฑด์ด ์ถฉ์กฑ๋ ๋๊น์ง ๊ธฐ๋ค๋ ค!" โ "์กฐ๊ฑด์ด ๋์ด, ์ด์ ์ผ์ด๋!" ์ด๋ฐ ์์ ํ๋ฆ์ ๋ฝ ๊ธฐ๋ฐ์ผ๋ก ๊ตฌํํ ์ ์๊ฒ ํด์ฃผ๋ ๊ฐ์ฒด๋ค.
public interface ReadWriteLock {
// ์ฝ๊ธฐ ์ ์ฉ ๋ฝ์ ๋ฐํ
Lock readLock();
// ์ฐ๊ธฐ ์ ์ฉ ๋ฝ์ ๋ฐํ
Lock writeLock();
}
ReadWriteLock์ ์ฝ๊ธฐ ๋ฝ(read lock) ๊ณผ ์ฐ๊ธฐ ๋ฝ(write lock) ๋ ์ข ๋ฅ์ ๋ฝ์ ์ ๊ณตํ๋ ๋ฝ ์ธํฐํ์ด์ค๋ค.
์ฝ๊ธฐ ๋ฝ (Read Lock)
์ฐ๊ธฐ ๋ฝ (Write Lock)
๊ฐ์ฅ ๋ง์ด ์ฐ์ด๋ ๊ตฌํ์ฒด๋ ReentrantReadWriteLock์ด ์กด์ฌํ๋ค.
ReadWriteLock lock = new ReentrantReadWriteLock();
Lock readLock = lock.readLock();
Lock writeLock = lock.writeLock();
๐ก ์ผ๋ฐ Lock (ReentrantLock)์ ํ๊ณ
๋ณดํต ReentrantLock์ด๋ synchronized๋
ํ ๋ฒ์ ๋จ ํ๋์ ์ค๋ ๋๋ง ์ ๊ทผํ ์ ์๊ฒ ํ๋ค.
์ฆ, ๋ฐ์ดํฐ ์ฝ๊ธฐ๋ง ํด๋ ๋ชจ๋ ์ค๋ ๋๊ฐ ์์๋๋ก ๊ธฐ๋ค๋ ค์ผ ํ๋ค.
Thread A: read() ์คํ ์ค
Thread B: ๊ธฐ๋ค๋ฆผ
Thread C: ๊ธฐ๋ค๋ฆผ
ํ์ง๋ง ์ฝ๊ธฐ(read) ์์
์ ๋ฐ์ดํฐ ๋ณ๊ฒฝ์ด ์๊ธฐ ๋๋ฌธ์,
์ฌ๋ฌ ์ค๋ ๋๊ฐ ๋์์ ์ฝ์ด๋ ์์ ํ๋ค.
์ด๋ฐ ์ํฉ์์ ๋จ์ผ ๋ฝ์ ์ฐ๋ฉด ๋ถํ์ํ๊ฒ ์ฑ๋ฅ์ด ๋จ์ด์ง๋ค.
๊ทธ๋์ ๋ฑ์ฅํ ๊ฒ ReadWriteLock์ด๋ค.
์ด๊ฑด ์ฝ๊ธฐ ์ ์ฉ ๊ตฌ๊ฐ์ ์ฌ๋ฌ ์ค๋ ๋๊ฐ ๋์์ ์ ๊ทผํ๊ฒ ํ๊ณ ,
์ฐ๊ธฐ ๊ตฌ๊ฐ์ ์ค์ง ํ๋์ ์ค๋ ๋๋ง ์ ๊ทผํ๊ฒ ๋ง๋ ๋ค.
| ์ํฉ | ์ค๋ช |
|---|---|
| ์ฝ๊ธฐ ๋น์ค์ด ๋์ ๋ | ๋๋ถ๋ถ์ ์์ ์ด ์ฝ๊ธฐ๋ผ๋ฉด, ๋์์ ์ฌ๋ฌ ์ค๋ ๋๊ฐ ์ ๊ทผ ๊ฐ๋ฅํด์ ์ฑ๋ฅ์ด ํฌ๊ฒ ํฅ์๋จ |
| ์ฐ๊ธฐ ๋น์ค์ด ๋ฎ์ ๋ | ๊ฐ๋๋ง ๋ฐ์ดํฐ๋ฅผ ์์ ํ๋ค๋ฉด, ์ ๊ธ ๊ฒฝํฉ(lock contention)์ ์ค์ |
| ์บ์, ์ค์ ๊ฐ, ์กฐํ API ๋ฑ | ์ฝ๊ธฐ๊ฐ ๋ง๊ณ ์ฐ๊ธฐ๊ฐ ๋๋ฌธ ๊ณณ์์ ๋งค์ฐ ์ ํฉ |
ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
Lock readLock = lock.readLock();
Lock writeLock = lock.writeLock();
ReentrantReadWriteLock์ ์ฝ๊ธฐ ์์ ๊ณผ ์ฐ๊ธฐ ์์ ์ ๊ตฌ๋ถํ์ฌ ๋์์ฑ์ ๋์ด๊ธฐ ์ํ ๋ฝ์ด๋ค.
์ฌ๋ฌ ๊ฐ์ ์ค๋ ๋๊ฐ ๋์์ ์ฝ๊ธฐ ์์ ์ ์ํํด๋ ๋ฐ์ดํฐ์ ์ผ๊ด์ฑ์ด ๊นจ์ง์ง ์๊ธฐ ๋๋ฌธ์, ์ฌ๋ฌ ์ค๋ ๋๊ฐ ๋์์ ์ฝ๊ธฐ ๋ฝ(ReadLock) ์ ์ป์ ์ ์๋ค.
์ฆ, ์ฝ๊ธฐ ๋ฝ์ ๊ณต์ ๋ฝ(Shared Lock)์ผ๋ก ๋์ํ์ฌ ์ํธ ๋ฐฐ์ ์์ด ๋ณ๋ ฌ์ ์ธ ์ฝ๊ธฐ ์ ๊ทผ์ ํ์ฉํ๋ฏ๋ก, ์ฝ๊ธฐ ์์ ์ด ๋ง์ ํ๊ฒฝ์์ ๋์์ฑ์ด ํฌ๊ฒ ํฅ์๋๋ค.
๋ฐ๋ฉด ์ฐ๊ธฐ ๋ฝ(WriteLock) ์ ๋ฐฐํ์ (Exclusive)์ผ๋ก ๋์ํ๋ค.
ํ๋์ ์ค๋ ๋๊ฐ ์ฐ๊ธฐ ๋ฝ์ ๋ณด์ ํ๊ณ ์๋ ๋์์๋ ๋ค๋ฅธ ์ด๋ค ์ค๋ ๋๋ ์ฝ๊ธฐ ๋ฝ์ด๋ ์ฐ๊ธฐ ๋ฝ์ ํ๋ํ ์ ์๋ค.
์ฝ๊ธฐ ๋ฝ์ด ์ ์ง๋๊ณ ์๋ ๋์์๋ ์ฐ๊ธฐ ๋ฝ์ ํ๋ํ ์ ์์ผ๋ฉฐ, ๋ง์ฝ ์ฐ๊ธฐ ๋ฝ์ ์ป์ผ๋ ค๋ ์ค๋ ๋๊ฐ ๋๊ธฐ ์ค์ธ๋ฐ ๊ณ์ํด์ ์๋ก์ด ์ฝ๊ธฐ ์์ฒญ์ด ๋ค์ด์จ๋ค๋ฉด, ์ฐ๊ธฐ ์ค๋ ๋๊ฐ ๋ฝ์ ์ป์ง ๋ชปํ๊ณ ๊ธฐ์(starvation) ์ํ์ ๋น ์ง ์ ์๋ค
.
์ด๋ฅผ ๋ฐฉ์งํ๊ธฐ ์ํด ReentrantReadWriteLock์ ์์ฑ ์ ๊ณต์ ๋ชจ๋(fair mode) ๋ก ์ค์ ํ ์ ์์ผ๋ฉฐ, ์ด ๊ฒฝ์ฐ ๋ฝ์ ๋๊ธฐ์ด์ ์์(FIFO)์ ๋ฐ๋ผ ๋ถ์ฌ๋์ด ๊ธฐ์ ํ์์ด ์ํ๋๋ค.
์ฝ๊ธฐ ๋ฝ์ด ํด์ ๋ ๋(unlock() ํธ์ถ ์), ๋ด๋ถ์ ์ผ๋ก ๋ณด์ ์ค์ธ ์ฝ๊ธฐ ๋ฝ์ ์๊ฐ ํ๋์ฉ ์ค์ด๋ค๋ฉฐ, ๋ชจ๋ ์ฝ๊ธฐ ๋ฝ์ด ํด์ ๋์ด ๊ฐ์๊ฐ 0์ด ๋๋ฉด ์ฐ๊ธฐ ๋ฝ์ ๋๊ธฐ ์ค์ธ ์ค๋ ๋๊ฐ ๋ฝ์ ํ๋ํ ์ ์๋ค.
๋ํ, ReentrantReadWriteLock์์ ์ฐ๊ธฐ ๋ฝ์ Condition ๊ฐ์ฒด๋ฅผ ์ง์ํ์ง๋ง, ์ฝ๊ธฐ ๋ฝ์ Condition์ ์ง์ํ์ง ์๋๋ค. ๋ฐ๋ผ์ readLock.newCondition()์ ํธ์ถํ๋ฉด UnsupportedOperationException์ด ๋ฐ์ํ๋ค.
| ๊ตฌ๋ถ | ReadWriteLock | ReentrantReadWriteLock | ReentrantLock |
|---|---|---|---|
| ํ์ | ์ธํฐํ์ด์ค (interface) | ๊ตฌํ ํด๋์ค (class) | ๊ตฌํ ํด๋์ค (class) |
| ๋ฝ์ ์ข ๋ฅ | ์ฝ๊ธฐ ๋ฝ, ์ฐ๊ธฐ ๋ฝ ๋ ๊ฐ์ง ์ ๊ณต | ์ฝ๊ธฐ ๋ฝ(ReadLock), ์ฐ๊ธฐ ๋ฝ(WriteLock) ๋ชจ๋ ๊ตฌํ | ๋จ์ผ ๋ฝ (์ฝ๊ธฐ/์ฐ๊ธฐ ๊ตฌ๋ถ ์์) |
| ๋์ ๋ฐฉ์ | ์ฝ๊ธฐ/์ฐ๊ธฐ ๊ฐ๋ ๋ง ์ ์ | ์ฝ๊ธฐ ๋ฝ์ ์ฌ๋ฌ ์ค๋ ๋๊ฐ ๊ณต์ ๊ฐ๋ฅ, ์ฐ๊ธฐ ๋ฝ์ ๋จ๋ ์ฌ์ฉ | ํ๋์ ์ค๋ ๋๋ง ์ ๊ทผ ๊ฐ๋ฅ (๋ฐฐํ์ ) |
| ์ฌ์ง์ ๊ฐ๋ฅ ์ฌ๋ถ | ์ ์ ์์ | ์ฌ์ง์ ๊ฐ๋ฅ | ์ฌ์ง์ ๊ฐ๋ฅ |
| ๊ณต์ ์ฑ ์ค์ (Fairness) | ์ ์ ์์ | ์ง์ (new ReentrantReadWriteLock(true)) | ์ง์ (new ReentrantLock(true)) |
| Condition ์ง์ ์ฌ๋ถ | ์ ์ ์์ | WriteLock๋ง ์ง์ / ReadLock์ ์ง์ํ์ง ์์ | ์ง์ |
| ๋์์ฑ ์์ค | ๊ฐ๋ ์ ์ค๊ฐ | ๋์ (์ฝ๊ธฐ ๋ณ๋ ฌ ํ์ฉ) | ๋ฎ์ (๋จ์ผ ์ ๊ทผ) |
| ์ฃผ์ ๋ฉ์๋ | readLock(), writeLock() | lock(), tryLock(), unlock(), getReadLockCount() ๋ฑ | lock(), tryLock(), unlock(), newCondition() |
| ์ ํฉํ ์ํฉ | ์ค๊ณ์ฉ (์ง์ ์ฌ์ฉ ๋ถ๊ฐ) | ์ฝ๊ธฐ ์์ ์ด ๋ง๊ณ ์ฐ๊ธฐ ์์ ์ด ์ ์ ๊ฒฝ์ฐ | ๋จ์ํ ์ํธ ๋ฐฐ์ ๊ฐ ํ์ํ ๊ฒฝ์ฐ |
| ๊ตฌํ ๊ธฐ๋ฐ | ์์ (์ธํฐํ์ด์ค) | AbstractQueuedSynchronizer (AQS) ๊ธฐ๋ฐ | AbstractQueuedSynchronizer (AQS) ๊ธฐ๋ฐ |
| ๊ฐ์ฒด ์์ฑ | ๋ถ๊ฐ๋ฅ (์ธํฐํ์ด์ค) | new ReentrantReadWriteLock() | new ReentrantLock() |