Java์์์ ์๊ณ์์ญ๊ณผ ๋ฐ๋๋ฝ ํด๊ฒฐ (sync, ๋ชจ๋ํฐ)
by JiwonDev์ฌ๋ฌ ํ๋ก์ธ์ค๊ฐ ํน์ ๋ฐ์ดํฐ๋ฅผ ๊ณต์ ํ ๋, ๊ฐ ํ๋ก์ธ์ค์์ ๊ณต์ ๋ฐ์ดํฐ๋ฅผ ์ ๊ทผ(access)ํ๋ ์ฝ๋๋ ๋์ ๋ถ๋ถ์ ์๊ณ์์ญ(Critical Section)์ด๋ผ๊ณ ๋งํฉ๋๋ค. ๊ณต์ ๋ ์์์ ์ฌ๋ฌ ๊ฐ์ ํ๋ก์ธ์๊ฐ ๋์์ ์ ๊ทผํด์ ์ฌ์ฉํ๋ฉด ์น๋ช ์ ์ธ ์ค๋ฅ๋ฅผ ๋ฐ์ ์ํฌ ์ ์๊ธฐ์ ํ ๋ฒ์ ํ๋์ ํ๋ก์ธ์๋ง ์ ๊ทผํ ์ ์๊ฒ ๋ง๋ค์ด์ผ ํฉ๋๋ค. ์ด๋ฅผ ์ํธ๋ฐฐ์ ๋ฌธ์ ๋ผ๊ณ ๋งํฉ๋๋ค.
์ด์์ฒด์ ์์ ์๊ณ์์ญ (Critical Section) ๋๊ธฐํ๋ ์์ฃผ ์ค์ํ ๋ถ๋ถ์ด๊ธฐ์, ์ด๋ฅผ ๋๊ธฐํ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ค๊ณ ์ฌ๋ฌ๊ฐ์ง ๋ฐฉ๋ฒ์ด ๋์ค๊ฒ ๋ฉ๋๋ค. ๊ทธ์ค ๋ํ์ ์ธ ๊ฒ์ด ์ธ๋งํฌ์ด, ๋ฎคํ ์ค, ๋ชจ๋ํฐ์ ๋๋ค.
# ์ฌ๋ฌ๊ฐ์ง ๋๊ธฐํ(์ํธ๋ฐฐ์ ) ๋ฐฉ๋ฒ
@ ์ธ๋งํฌ์ด(Semaphore)
์๋ ์ ์ด์ฐจ๊ฐ ๋ถ๋ชํ์ง ์๊ฒ ํ์ํ๋ ๊น๋ฐ์ ์ธ๋งํฌ๋ผ๊ณ ๋ถ๋ฆ
๋๋ค. ๋ฆฌ์์ค์ ์ํ๋ฅผ ๋ํ๋ด๋ ๊ฐ๋จํ ์นด์ดํฐ์ด๋ฉฐ ๊ณต์ ๋ ์์์ ๋ฐ์ดํฐ ํน์ ์๊ณ์์ญ(Critical Section) ๋ฑ์ ์ฌ๋ฌ Process ํน์ Thread๊ฐ ์ ๊ทผํ๋ ๊ฒ์ ๋ง์์ค๋๋ค. ์ฆ, ๋๊ธฐํ ๋์์ด ํ๋ ์ด์์
๋๋ค.
@ ๋ฎคํ ์ค(Mutex)
์ํธ๋ฐฐ์ (Mutual Exclusion)์์ ๋์จ ๋ง๋ก ๊ณต์ ๋ ์์์ ๋ฐ์ดํฐ ํน์ ์๊ณ์์ญ(Critical Section)์ ๊ฐ์ง ์ฐ๋ ๋๋ค์ ๋ฐํ์์ ์๋ก ๊ฒน์น์ง ์๊ฒ ๊ฐ๊ฐ ๋จ๋
์ผ๋ก ์คํ๋๊ฒ ํ๋ ๊ธฐ์ ์
๋๋ค. ๋ค์ค ํ๋ก์ธ์ค๋ค์ ๊ณต์ ๋ฆฌ์์ค์ ๋ํ ์ ๊ทผ์ ์กฐ์จํ๊ธฐ ์ํด locking๊ณผ unlocking์ ์ฌ์ฉํฉ๋๋ค.
์์ ๋ฎคํ ์ค์ ์ธ๋งํฌ๋ ๋ ๋ค ๋ฐ์ดํฐ์ ๋ฌด๊ฒฐ์ฑ์ ๋ณด์ฅํ๊ธฐ๋ ์ด๋ ต์ต๋๋ค. ๋ฐ๋๋ฝ์ด ๋ฐ์ํ ์๋ ์๊ธฐ์ ์ข ๋ ๋ณต์กํ ๋งค์ปค๋์ฆ์ ์ถ๊ฐ๋ก ์ ์ฉํด์ผํฉ๋๋ค.
@ ๋ชจ๋ํฐ
ํ๋์ ์ด์์ฒด์ ๋ ์๊ณ์์ญ ๋๊ธฐํ(์ํธ๋ฐฐ์ ๋ฐฉ๋ฒ)์ผ๋ก ์ธ๋งํฌ, ๋ฎคํ ์ค๋ณด๋ค๋ ๋ชจ๋ํฐ๋ฅผ ๋ง์ด ์ฌ์ฉํฉ๋๋ค. ๋ชจ๋ํฐ๋ 2๊ฐ์ ํ(์ํธ๋ฒ ํ ํ, ์กฐ๊ฑด๋๊ธฐ ํ)๋ก ๊ตฌ์ฑ๋์ด์ง๋๋ค.
- ์ํธ๋ฐฐํ ํ๋ ๋ง๊ทธ๋๋ก ๊ณต์ ์์์ ํ๋์ ํ๋ก์ธ์ค๋ง ์ง์ ํ๋๋ก ํ๊ธฐ ์ํ ํ์ ๋๋ค.
- ์กฐ๊ฑด๋๊ธฐ ํ๋ ์ด๋ฏธ ๊ณต์ ์์์ ์ฌ์ฉํ๊ณ ์๋ ํ๋ก์ธ์ค์ wait() ํธ์ถ์ ํตํด ์กฐ๊ฑด๋๊ธฐ ํ๋ก ๋ค์ด๊ฐ ์ ์์ต๋๋ค.
๊ทธ๋ฆผ์ ๋ณด๋ฉด ์ดํด๊ฐ ์ฝ์ต๋๋ค.
- ์ผ์ชฝ ํ์ ์์์ด ํ์ํ ์ฐ๋ ๋๋ค์ ๋ด์, ํ๊ฐ์ฉ ์๊ณ์์ญ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ฌ์ฉํ๊ฒ ํด์ค๋๋ค.
- ์๊ณ์์ญ์ ์ ๊ทผํ์์ผ๋ I/O๋ฑ์ผ๋ก ์์ง ๋ฐ์ดํฐ๊ฐ ์ค๋น๋์ง ์์ ํด๋น ์ฐ๋ ๋๊ฐ ๊ธฐ๋ค๋ ค์ผ ํ๋ ๊ฒฝ์ฐ wait()์ผ๋ก ์ค๋ฅธ์ชฝ ํ์ ๋ค์ด๊ฐ ์ ์์ต๋๋ค. ์ด๋ ์ฐ๋ ๋๋ฅผ ์ข ๋ฃํ๋๊ฒ ์๋๋ผ ์ ์ ๊ธฐ๋ค๋ฆฌ๊ฒ(block)ํ๋ ๊ฐ๋ ์ ๋๋ค.
- ์ค๋ฅธ์ชฝ ํ(์กฐ๊ฑด๋๊ธฐ)์ ๋ค์ด๊ฐ์๋ ๋ค๋ฅธ ์ฐ๋ ๋์์ notify()๋ก ๊นจ์์ค ์ ์์ต๋๋ค. ๋ค๋ง ์ด๋ฏธ ์๊ณ์์ญ์ ์ฌ์ฉ์ค์ด๊ฑฐ๋ ์์ ๋ค๋ฅธ ์ฐ๋ ๋๊ฐ ๋๊ธฐ์ค์ด๋ผ๋ฉด notify()๋ฅผ ํธ์ถ ํ๋คํด์ ๋ฐ๋ก ์คํ๋๋๊ฑด ์๋๋๋ค.
# ์๋ฐ์ synchronized ๋ชจ๋ํฐ
์๋ฐ๋ ์ฐ๋ ๋ ๋๊ธฐํ ๋ฐฉ๋ฒ์ผ๋ก ๋ชจ๋ํฐ๋ฅผ ์ ๊ณตํฉ๋๋ค. synchronzied ํค์๋๋ฅผ ์ด์ฉํด ์๊ณ๊ตฌ์ญ์ ๋ง๋ค ์ ์๊ณ , Object ์ ๋ด์ฅ๋ ๋ฉ์๋ (wait, notify)๋ฅผ ์ด์ฉํ์ฌ ๋ชจ๋ํฐ๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค.
- wait(): ํธ์ถํ ์ฐ๋ ๋๋ฅผ ์กฐ๊ฑด๋๊ธฐ ํ์ ์ฝ์ ํ๋ค.
- notify(): ์กฐ๊ฑด๋๊ธฐ ํ(waiting pool)์ ์๋ ํ๋์ ์ฐ๋ ๋๋ฅผ ๊นจ์์ค๋ค.
- notifyAll(): ์กฐ๊ฑด๋๊ธฐ ํ(waiting pool)์ ์๋ ๋ชจ๋ ์ฐ๋ ๋๋ฅผ ๊นจ์์ค๋ค.
// ์๊ณ๊ตฌ์ญ์ '๊ณต์ ๋ณ์์ ์ ๊ทผํ๋ ์ฝ๋ ๊ตฌ๊ฐ'์ ์๋ฏธํ๋ค. ๋ฉ๋ชจ๋ฆฌ ์์ฒด๊ฐ ์๋๋ค.
class C {
private int value, ...; // ์ฌ์ฉํ ๊ณต์ ๋ณ์
public synchronized void Foo() {
// ์ด ๋ฉ์๋์์ ์ ๋ถ ์๊ณ๊ตฌ์ญ
}
public void Goo() {
synchronized {
// synchronized {~} ๋ธ๋ญ์ ์ ๋ถ ์๊ณ๊ตฌ์ญ
// ์๊ณ๊ตฌ์ญ์ ์ ๊ฒ๋ง๋ค์๋ก ์ฑ๋ฅ์ ์ข๋ค. ๋๊ธฐํ๋ ๋น์ฉ์ด ํฐ ์์
์ด๋ค.
}
}
}
# ์ ํต์ ์ธ ๋๊ธฐํ ๋ฌธ์ ๋ค
@1. Producer and Consumer Problem( ์์ฐ์-์๋น์ ๋ฌธ์ )
๋ค๋ฅธ๋ง๋ก ์ ํํ ๋ฒํผ ๋ฌธ์ (Bounded Buffer Problem)๋ผ๊ณ ๋ ํ๋ค. ์ถ๊ธ๊ณผ ์ ๊ธ, ์ ์๊ณผ ์ฌ์ฉ์ฒ๋ผ ์์ฐ์๊ฐ ๋ฐ์ดํฐ๋ฅผ ์์ฐํ๋ฉด ์๋น์๊ฐ ๊ทธ๊ฒ์ ์๋นํ๋ ๊ตฌ์กฐ์์ ์ ์ฅ๊ณต๊ฐ์ธ buffer๊ฐ ๋ฌดํํ์ง ์์ ๋ ์๊ธฐ๋ ๋ฌธ์ ์ด๋ค.
์ ์ด๋ฐ๋ฌธ์ ๊ฐ ๋ฐ์ํ ๊น? ๋ํ์ ์ผ๋ก Busy-Wait ๋ฌธ์ (์์ฐ์ ๋ฐ์๋ฐ ์๋น์๋ ์ค๋ ๊ธฐ๋ค๋ ค์ผํ๋)๊ฐ ์๋ค.
- ์์ฐ๋ ๋ฐ์ดํฐ๋ ๋ฒํผ์ ์ ์ฅํ๋ค.
- ํ์ค ์์คํ ์์ ๋ฒํผ์ ํฌ๊ธฐ๋ ํ๊ณ๊ฐ ์๋ค. ์ฆ, ๋ฒํผ๊ฐ ๊ฐ๋์ฐจ๋ฉด ๋ ์ด์ ์์ฐํ ์ ์๋ค.
- ์์ฐ๋ณด๋ค ์๋น๊ฐ ๋๋ฌด ๋น ๋ฅด๋ฉด ๋ฒํผ๊ฐ ๋น์ด๋ฒ๋ฆฐ๋ค. ์๋นํ๋ ค๊ณ ํด๋ ๋จ์ ์์์ด ์์ด ๊ณ์ ๊ธฐ๋ค๋ฆฌ๊ฒ ๋๋ค.
- ์ฌ๋ฌ ์ฐ๋ ๋์ ์ ๊ทผ์ ๋๊ธฐํ๋ฅผ ์ ๋๋ก ํด์ฃผ์ง ์๋๋ค๋ฉด ๋ฒํผ count๊ฐ ์์ (-1)๊ฐ ๋ ์๋ ์๋ค.
- [๋จ์ ์์์ด ์์ด์ ์๋น์ ๊ธฐ๋ค๋ฆผ] + [์ฐ๋ ๋ ๋๊ธฐํ ๋๋ฌธ์ ์์ฐ์ ์์ ์ถ๊ฐ์๋จ] = ํ๋ก๊ทธ๋จ ๋ฉ์ถค
์ฐธ๊ณ ๋ก ์ด๋ ๊ฒ ๊ต์ฐฉ์ํ์ ๋น ์ ธ ์์ํ ํ๋ก๊ทธ๋จ์ด ๋ฉ์ถ๋๊ฑธ ๋ฐ๋๋ฝ(Dead-lock)์ด๋ผ๊ณ ๋งํ๋ค.
@2. Reader-Writer Problem
๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ๋๊ธฐํ๋ฅผ ํ ๋ ์๊ธฐ๋ ์ฑ๋ฅ ๋ฌธ์ ์ด๋ค. ๋ฌด์ง์ฑ์ผ๋ก Reader์ Writer๋ฅผ ๊ฐ์ด ๋๊ธฐํํ๊ฒ ๋๋ฉด ๊ทธ๋ฅ ์ฝ๊ธฐ๋ง 100๋ฒ ํ๋๋ฐ๋ 100๋ฒ ๋ค lock์ ๊ฑธ์ด๋ฒ๋ฆฐ๋ค. ์ด๋ ์๋นํ ๋นํจ์จ์ ์ด๊ณ , DB ์ฑ๋ฅ์ ํฌ๊ฒ ํ๋ฝ์ํจ๋ค.
@3. Dining Philosopher Problem (์์ฌํ๋ ์ฒ ํ์ ๋ฌธ์ )
์ํํ ์ด๋ธ์์, 5๋ช ์ด ๋ฐฅ์ ๋จน๋๋ฐ ์ ๊ฐ๋ฝ์ด 4๊ฐ์ธ ๊ฒฝ์ฐ๋ฅผ ๋งํ๋ค. ์ฒ ํ์๋ค์ ๊ต์์ด ์์ด์ ๋ฉ๋ฆฌ์๋ ์ ๊ฐ๋ฝ์ ๋นผ์์ ์ค์ง๋ ์๊ณ , ์์์ ์๋ ์ ๊ฐ๋ฝ๋ง์ ์ฌ์ฉํ๋ค๊ณ ๊ฐ์ ํ๋ค.
์ ๊ฐ๋ฝ์ด ๊ณต์ ๋๋ ๋ฉ๋ชจ๋ฆฌ, ์ ๊ฐ๋ฝ ์์ชฝ์ ์์์๋ ์ฌ๋์ ํด๋น ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ฌ์ฉํ๋ ์ฐ๋ ๋์ด๋ค. ์ค์ ๋ก ์์คํ ์์์ ์ด๋ฐ ์์ผ๋ก ๊ณต์ ์์์ด ์ฎ์ด์์ ์ ์๋ค. ์ด ๊ฒฝ์ฐ ๊ต์ฐฉ์ํ์ ๋น ์ง ๋ฐ๋๋ฝ์ด ์๊ธธ ์๋ ์๊ณ ํน์ ์ฐ๋ ๋(์ฌ๋)์ ์์ํ ์์์ ํ ๋น๋ฐ์ง ๋ชปํด ๊ตถ์ด์ฃฝ๋(Starvation) ๋ฌธ์ ๊ฐ ์์ ์ ์๋ค.
# ์๋ฐ์ ๋๊ธฐํ ๋ฌธ์ ํด๊ฒฐ์ฑ
@ 1. ์๋น์์ ์์ฐ์
๋ฌธ์ : ๋ฒํผ๊ฐ ๋น์์ ๋ ์๋น์๊ฐ ๋ฒํผ lock์ ๊ฑธ๊ณ ํ์ด์ฃผ์ง ์๋๋ค. ๊ทธ๋ผ ์์ฐ์๋ ๋ฒํผ์ ์์์ ๋ชป์ฑ์ด๋ค.
ํด๊ฒฐ : ์์์ด ์๋ค๋ฉด ์๋น์ lock์ ๊ฑธ์ง ๋ง๊ณ wait()์ผ๋ก ์ฌ์๋์. ์์ฐ์๊ฐ ์์์ ์ถ๊ฐํ ๋ notify()๋ก ์๋ฆฌ์.
ํ์ง๋ง ์ด๋ ๊ฒ ํด๊ฒฐํ๋ ๊ฒฝ์ฐ, ๋จ์ํ ํ์ ๋ฃ๊ณ ๋บด๋ ๊ฒ์ด์ง ์ ์ค๋ ๋๊ฐ wait๋์๋์ง ์ํ๋ฅผ ์ ์ ์๋ค.
์ฆ wait()์ด ๋ฒํผ๊ฐ ๊ฐ๋์ฐจ์ ์๋น์๋ฅผ ์ํด ์๋ํ๊ฑด์ง ์๋๋ฉด ์์ ๋ฌธ์ ์ฒ๋ผ ์์ฐ์๋ฅผ ๊ธฐ๋ค๋ฆด๋ ค๊ณ wait์ ํ๊ฑด์ง ์ ์ ์๊ณ , ์ด๋์์ ์ notify()๋ฅผ ๊ฑธ์ด ๋ค์ ๋์์์ผ์ผ ํ๋์ง๋ ์๋นํ ์ ๋งคํด์ง๋ค.
=> ๊ทธ๋์ JDK 1.5์๋ ์ํ๊ฐ๋ ํจ๊ป ๊ด๋ฆฌํ ์ ์๊ณ , ๋ ๋ค์ํ ๋๊ธฐํ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ ๋์์ฑ ํจํค์ง (java.util.concurrent)๋ฅผ ์ ๊ณตํ๋ค.
2021.07.27 - [Backend/Java] - ์ฐ๋ ๋์ ๋๊ธฐํ (synchronization)
'๐๊ธฐ๋ณธ ์ง์ > CS ๊ธฐ๋ณธ์ง์' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
DB ์ธ๋ฑ์ค์์๋ ์ HashTable์ ์ฌ์ฉํ์ง ์์๊น? (0) | 2024.01.10 |
---|---|
๋คํธ์ํฌ L4, L7 ๋ก๋๋ฐธ๋ฐ์ฑ (Load balancing) (0) | 2021.09.08 |
์ ์์ผ๊ณผ ์ต์คํธ๋ฆผ ํ๋ก๊ทธ๋๋ฐ(Agile , XP) (0) | 2021.08.25 |
ํธ๋์ญ์ ๊ฒฉ๋ฆฌ์์ค(DB Isolation Level) (0) | 2021.08.10 |
I/O์ Sync์ Blocking ๊ทธ๋ฆฌ๊ณ Multiplexing (0) | 2021.07.28 |
๋ธ๋ก๊ทธ์ ์ ๋ณด
JiwonDev
JiwonDev