๐ ๊ฒฝ์ ์ํ
[OS] ๋ฉํฐ์ค๋ ๋์์ ๊ฒฝ์ ์ํ ํด๊ฒฐ: ์ํธ ๋ฐฐ์ (๋ฎคํ ์ค์ ์ธ๋งํฌ์ด)
๐ ์ค๋ ์ฃผ์ ์ธ ๊ฒฝ์ ์ํ์ ์ํธ ๋ฐฐ์ ๋ ๋ฉํฐ์ค๋ ๋ ์ธ์๋ ๋ฉํฐํ๋ก์ธ์ค์์๋ ๋ฐ์ํ ์ ์๋ ๋ฌธ์ ์ด์ง๋ง์ ๊ฐ ๋ฉํฐ์ค๋ ๋์ ๋ํด ๋ฐฐ์ฐ๋ฉฐ ์ ๋ฆฌํ ๋ด์ฉ์ผ๋ก, ๋ฉํฐ์ค๋ ๋์ ๋ํด์๋ง ์ค์ ์
syleeblog.tistory.com
์ด์ ๊ธ์์๋
์ด์ ์ฒด์ ๊ด์ ์์ ๊ฒฝ์ ์ํ์ ์ ์ ๊ทธ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํ ์ํธ ๋ฐฐ์ ์ ๋ํด ์์๋ดค์ต๋๋ค.
์ด๋ฒ ๊ธ์์๋
๋ฉํฐ์ค๋ ๋๋ฅผ ์ง์ํ๋ Java์์ ๊ฒฝ์ ์ํ๊ฐ ๋ฐ์ํ๋ ๊ฒฝ์ฐ ํด๊ฒฐ ์ ๋ต์ ์์๋ณด๊ฒ ์ต๋๋ค.
์ด์ ๊ธ์์ ๊ฒฝ์ ์ํ์ ๋ํด ์์ธํ ๋ค๋ฃจ์๋๋ฐ ๊ฐ๋จํ๊ฒ ์ ๋ฆฌํ์๋ฉด
๊ฒฝ์ ์ํ(Race Condition)๋, ๋ ์ด์์ ์ค๋ ๋๊ฐ ๋์์ ๊ฐ์ ์์์ ์ ๊ทผํ๊ณ ์์ ํ๋ ค๊ณ ํ ๋
๋ฉํฐ์ค๋ ๋ ํ๊ฒฝ์์ ๊ณต์ ์์์ ์ ๋๋ก ๋๊ธฐํ๋์ง ์์, ์์ธก ๋ถ๊ฐ๋ฅํ ๊ฒฐ๊ณผ๋ ๋ฐ์ดํฐ ๋ถ์ผ์น๊ฐ ๋ฐ์ํ๋ ๋ฌธ์ ์ ๋๋ค.
๐ synchronized ํค์๋
Java์์ ๊ฐ์ฅ ๊ธฐ๋ณธ์ ์ธ ๋๊ธฐํ ์๋จ์ ๋๋ค. ํน์ ๋ฉ์๋๋ ๋ธ๋ก์ synchronized๋ฅผ ์ง์ ํ๋ฉด ํ ๋ฒ์ ํ๋์ ์ค๋ ๋๋ง ํด๋น ์ฝ๋์ ์ง์ ํ ์ ์๊ฒ ๋ฉ๋๋ค.
public synchronized void increment() {
counter++;
}
- โ
์ฅ์
- ์ฌ์ฉ์ด ๊ฐ๋จํ๊ณ ์ง๊ด์ ์ ๋๋ค.
- ๋ฉ์๋ ์ ์ฒด ํน์ ํน์ ๋ธ๋ก์ ์ ์ฉํ ์ ์์ต๋๋ค.
- โ ๏ธ ์ฃผ์
- ์ธ๋ฐํ ์ ์ด๋ ์ด๋ ต์ต๋๋ค.
๐ Lock ์ธํฐํ์ด์ค
java.util.concurrent.locks.Lock์ synchronized๋ณด๋ค ๋ ์ ๊ตํ ๋๊ธฐํ ์ ์ด๋ฅผ ๊ฐ๋ฅํ๊ฒ ํด์ค๋๋ค.
์ฃผ์ ๊ตฌํ์ฒด๋ก ReentrantLock์ด ์์ต๋๋ค.
lock.lock();
try {
// ์์
์ํ
} finally {
lock.unlock();
}
- ๊ณต์ ์ฑ ์ค์ , ํ์์์ ๋๊ธฐ, ์กฐ๊ฑด ๋ณ์(Condition) ๋ฑ์ ์ค์ ํ ์ ์์ต๋๋ค.
- finally ๋ธ๋ก์์ ๋ฐ๋์ unlock()์ ํธ์ถํด ๋ฝ์ ํ์ด์ผ ํฉ๋๋ค.
๐ Atomic ํด๋์ค ์ฌ์ฉ
AtomicInteger, AtomicLong ๋ฑ์ ๋ด๋ถ์ ์ผ๋ก CAS(Compare-And-Swap) ๊ธฐ๋ฒ์ ์ฌ์ฉํ์ฌ
๋ฝ ์์ด๋ ์ค๋ ๋ ์์ ํ, ์์์ ์ฐ์ฐ์ด ๊ฐ๋ฅํ๊ฒ ํด์ค๋๋ค.
AtomicInteger counter = new AtomicInteger();
counter.incrementAndGet();
- โ
์ฅ์
- ๋น๋๊ธฐ ํ๊ฒฝ์์๋ ์์ ํ๊ฒ ๊ฐ์ ์์ ํ ์ ์์ต๋๋ค.
- ๋ฝ์ ์ฌ์ฉํ์ง ์์ ๊ฐ๋จํ ์ฐ์ฐ์์ ์๋๊ฐ ๋งค์ฐ ๋น ๋ฆ ๋๋ค.
- โ ๏ธ ์ฃผ์
- ๋ณต์กํ ์ฐ์ฐ์๋ ์ ์ ํ์ง ์์ต๋๋ค.
๐ Concurrent ์ปฌ๋ ์ ํ์ฉ
ConcurrentHashMap, CopyOnWriteArrayList ๋ฑ์ ๋ฉํฐ์ค๋ ๋ ํ๊ฒฝ์์ ์์ ํ๊ฒ ๋์ํ๋๋ก ์ค๊ณ๋ ์ปฌ๋ ์ ์ ๋๋ค.
์ง์ ๋๊ธฐํ ์ฝ๋๋ฅผ ์์ฑํ์ง ์์๋ ๋๊ธฐ ๋๋ฌธ์ ์์ ์ฑ๊ณผ ์์ฐ์ฑ์ ๋์์ ํ๋ณดํ ์ ์์ต๋๋ค.
ConcurrentHashMap, CopyOnWriteArrayList, ConcurrentLinkedQueue ๋ฑ
๋ฉํฐ ์ค๋ ๋ ํ๊ฒฝ์์๋ ์์ ํ ์ปฌ๋ ์ ์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
๐ ๋ถ๋ณ ๊ฐ์ฒด(Immutable Object) ํ์ฉ
๊ฐ๋ฅํ๋ฉด ๊ณต์ ์์์ ์ฐ์ง ์๋๋ก ์ค๊ณํ๋ ๊ฒ์ด ๊ฐ์ฅ ์ข์ ๋ฐฉ๋ฒ์ ๋๋ค.
๊ฒฝ์ ์ํ ์์ฒด๋ฅผ ํํผํ๊ธฐ ์ํด ๋ถ๋ณ ๊ฐ์ฒด๋ฅผ ํ์ฉํ ์ ์์ต๋๋ค.
๋ถ๋ณ ๊ฐ์ฒด๋, ์ํ๊ฐ ๋ณํ์ง ์๋ ๊ฐ์ฒด์ ๋๋ค.
ํ๋๊ฐ ๋ชจ๋ final๋ก ์ ์ธ๋๊ณ , ์ธ๋ถ์์ ์์ ํ ์ ์๋ ๊ฐ์ฒด์ ๋๋ค.
public final class User {
private final String name;
private final int age;
public User(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() { return name; }
public int getAge() { return age; }
}
์ํ ๋ณ๊ฒฝ์ด ์๊ธฐ ๋๋ฌธ์ ๊ฒฝ์ ์ํ ์์ฒด๊ฐ ๋ฐ์ํ์ง ์์ต๋๋ค.
๋ฐ๋ผ์ ์ค๋ ๋ ๊ฐ ๊ณต์ ํด๋ ์์ ํฉ๋๋ค.
๊ฒฐ๋ก
๊ฒฝ์ ์ํ๋ ๋ฉํฐ์ค๋ ๋์์ ํํ๊ฒ ๋ฐ์ํ๋ ๋ฌธ์ ์ ๋๋ค.
๋ฌธ์ ์ํฉ์ ๋ง๋ ๋๊ธฐํ ์ ๋ต์ ์ ํํ์ฌ ์ฑ๋ฅ๊ณผ ์์ ์ฑ์ ๊ท ํ์ ์ ์งํด์ผ ํฉ๋๋ค.