๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

๋นˆ ๊ตฌ๋ฉ ์ฑ„์šฐ๊ธฐ

[Java] ๋ฎคํ…์Šค Mutex & ์„ธ๋งˆํฌ์–ด Semaphore

์ถœ์ฒ˜

ChatGPT

 


1. ๋ฎคํ…์Šค Mutex

Mutaul Exclusion์˜ ์•ฝ์ž.

ํ•œ ๋ฒˆ์— ํ•˜๋‚˜์˜ ์Šค๋ ˆ๋“œ๋งŒ ๊ณต์œ  ์ž์›์— ์ ‘๊ทผํ•˜๋„๋ก ๋ณด์žฅํ•œ๋‹ค.

Lock Mechanism ์ž ๊ธˆ ๋งค์ปค๋‹ˆ์ฆ˜

๋ฝ(lock)์€ ์ž์›์„ ์‚ฌ์šฉํ•  ๋Œ€ ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ์˜ ์ ‘๊ทผ์„ ์ฐจ๋‹จํ•˜๊ณ , ์ž์›์˜ ์†Œ์œ ๊ถŒ์„ ๊ฐ–๋Š” ๋ฐฉ์‹์ด๋‹ค. ๋ฎคํ…์Šค๋Š” ์ž์›์„ ์ž ๊ทธ๋Š”(lock) ์—ญํ• ์„ ํ•˜๋ฉฐ, ๊ทธ ์ž์›์€ ๋ฎคํ…์Šค๋ฅผ ์†Œ์œ ํ•œ ํ•˜๋‚˜์˜ ์Šค๋ ˆ๋“œ๋งŒ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค.

Lock Mechanism์˜ ์ž‘๋™ ๋ฐฉ์‹

  • ์Šค๋ ˆ๋“œ๋Š” ์ž์›์— ์ ‘๊ทผํ•  ๋•Œ ๋ฝ์„ ํš๋“ํ•œ๋‹ค.
  • ์ž์› ์‚ฌ์šฉ์ด ๋๋‚˜๋ฉด ๋ฝ์„ ํ•ด์ œํ•ด ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๊ฐ€ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•œ๋‹ค.

ํŠน์ง•

  • ๋ฝ์„ ์‚ฌ์šฉํ•˜๋Š” ์Šค๋ ˆ๋“œ๋งŒ ์ž์›์„ ์‚ฌ์šฉํ•˜๊ณ , ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๋Š” ๋ฝ์ด ํ•ด์ œ๋  ๋•Œ๊นŒ์ง€ ๋Œ€๊ธฐํ•ด์•ผ ํ•œ๋‹ค.
  • ๋ฎคํ…์Šค๋Š” ๋‹จ์ผ ์Šค๋ ˆ๋“œ์˜ ์ ‘๊ทผ๋งŒ์„ ํ—ˆ์šฉํ•ด ์Šค๋ ˆ๋“œ ์•ˆ์ „์„ฑ์„ ๋ณด์žฅํ•œ๋‹ค.

๊ตฌํ˜„

์ž๋ฐ”์—์„œ๋Š” synchronized ํ‚ค์›Œ๋“œ๋‚˜ ReentrantLock ํด๋ž˜์Šค๋ฅผ ์ด์šฉํ•ด ๋ฎคํ…์Šค๋ฅผ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

1. synchronized

ํŠน์ • ์ฝ”๋“œ ๋ธ”๋ก์ด๋‚˜ ๋ฉ”์†Œ๋“œ์— ์‚ฌ์šฉ๋˜์–ด, ํ•ด๋‹น ์ฝ”๋“œ๊ฐ€ ์‹คํ–‰๋  ๋•Œ ๋‹จ ํ•˜๋‚˜์˜ ์Šค๋ ˆ๋“œ๋งŒ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•œ๋‹ค.

public synchronized void criticalSection() {
    // ํ•˜๋‚˜์˜ ์Šค๋ ˆ๋“œ๋งŒ ์ ‘๊ทผ ๊ฐ€๋Šฅ
}

 

2. ReentrantLock

๋” ์ •๊ตํ•œ ๋ฝ์„ ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ๋œ๋‹ค. tryLock(), lockInterruptibly()์™€ ๊ฐ™์€ ๋‹ค์–‘ํ•œ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•œ๋‹ค.

ReentrantLock lock = new ReentrantLock();

public void criticalSection() {
    lock.lock();
    try {
        // ํ•˜๋‚˜์˜ ์Šค๋ ˆ๋“œ๋งŒ ์ ‘๊ทผ ๊ฐ€๋Šฅ
    } finally {
        lock.unlock();
    }
}

 

2. ์„ธ๋งˆํฌ์–ด Semaphore

ํŠน์ • ์ž์›์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ์Šค๋ ˆ๋“œ ์ˆ˜๋ฅผ ์ œํ•œํ•˜๋Š” ๋™๊ธฐํ™” ๊ธฐ๋ฒ•

Signal Mechanism ์‹ ํ˜ธ ๋ฉ”์ปค๋‹ˆ์ฆ˜

์Šค๋ ˆ๋“œ๊ฐ€ ์ž์›์„ ์š”์ฒญํ•  ๋•Œ, ์„ธ๋งˆํฌ์–ด์˜ ์‹ ํ˜ธ(ํ—ˆ๊ฐ€)๋ฅผ ํ†ตํ•ด ์ž์›์˜ ์ ‘๊ทผ ์—ฌ๋ถ€๋ฅผ ์•Œ๋ ค์ฃผ๊ณ , ๊ทธ ์‹ ํ˜ธ์— ๋”ฐ๋ผ ์ ‘๊ทผ์ด ํ—ˆ์šฉ๋˜๊ฑฐ๋‚˜ ๋Œ€๊ธฐํ•˜๊ฒŒ ๋˜๋Š” ๋ฐฉ์‹์ด๋‹ค.

์ž‘๋™ ๋ฐฉ์‹

  • ์Šค๋ ˆ๋“œ๊ฐ€ ์ž์›์— ์ ‘๊ทผํ•˜๋ ค๊ณ  ํ•  ๋•Œ, acquire()๋ฅผ ํ˜ธ์ถœํ•ด ์„ธ๋งˆํฌ์–ด์˜ ํ—ˆ๊ฐ€๋ฅผ ์š”์ฒญํ•œ๋‹ค.
  • ํ—ˆ๊ฐ€๊ฐ€ ๋‚จ์•„ ์žˆ์œผ๋ฉด ์ž์›์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๊ณ , ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ๋Œ€๊ธฐ ์ƒํƒœ๊ฐ€ ๋œ๋‹ค.
  • ์ž์› ์‚ฌ์šฉ์ด ๋๋‚œ ํ›„ release()๋ฅผ ํ˜ธ์ถœํ•ด ํ—ˆ๊ฐ€๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ณ , ๋Œ€๊ธฐ ์ค‘์ธ ๋‹ค๋ฅด ์Šค๋ ˆ๋“œ๊ฐ€ ์ž์›์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋„๋ก ์‹ ํ˜ธ๋ฅผ ๋ณด๋‚ธ๋‹ค.
  • acquire() : ์„ธ๋งˆํฌ์–ด์˜ ํ—ˆ๊ฐ€(permission)์„ ์š”์ฒญํ•˜๋Š” ์—ญํ• ์„ ํ•œ๋‹ค. ์„ธ๋งˆํฌ์–ด์˜ ํ˜„์žฌ ํ—ˆ๊ฐ€ ๊ฐ€๋Šฅ ์ˆ˜๊ฐ€ 0๋ณด๋‹ค ํฌ๋ฉด ์Šค๋ ˆ๋“œ๋Š” ์ฆ‰์‹œ ์ ‘๊ทผ ๊ถŒํ•œ์„ ์–ป๊ณ  ์ž์›์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค. ๋ฐ˜๋ฉด, ํ—ˆ๊ฐ€ ๊ฐ€๋Šฅ ์ˆ˜๊ฐ€ 0์ด๋ผ๋ฉด, ํ•ด๋‹น ์Šค๋ ˆ๋“œ๋Š” ์ž์›์— ์ ‘๊ทผํ•˜๊ธฐ ์œ„ํ•ด ๋Œ€๊ธฐ ์ƒํƒœ์— ๋†“์ด๊ฒŒ ๋œ๋‹ค.
  • release() : ์ž์›์˜ ์‚ฌ์šฉ์ด ๋๋‚œ ํ›„, ์ ‘๊ทผ ๊ถŒํ•œ์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ์—ญํ• ์„ ํ•œ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ๋‹ค๋ฅธ ๋Œ€๊ธฐ ์ค‘์ธ ์Šค๋ ˆ๋“œ๊ฐ€ ์ž์›์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค. 

ํŠน์ง•

์„ธ๋งˆํฌ์–ด๋Š” ํ—ˆ์šฉ๋œ ์ˆ˜์˜ ์“ฐ๋ ˆ๋“œ๊นŒ์ง€๋งŒ ์ž์›์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋„๋ก ์ œ์–ดํ•œ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์„ธ๋งˆํฌ์–ด๊ฐ€ 3์ด๋ผ๋ฉด ์ตœ๋Œ€ 3๊ฐœ์˜ ์Šค๋ ˆ๋“œ๊ฐ€ ๋™์‹œ์— ์ž์›์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค.

 

1. ๋ฐ”์ด๋„ˆ๋ฆฌ ์„ธ๋งˆํฌ์–ด

๊ฐ’์ด 1์ธ ์„ธ๋งˆํฌ์–ด๋กœ, ๋ฎคํ…์Šค์™€ ์œ ์‚ฌํ•˜๊ฒŒ ์ž‘๋™ํ•œ๋‹ค.

 

2. ์นด์šดํŒ… ์„ธ๋งˆํฌ์–ด

1๋ณด๋‹ค ํฐ ๊ฐ’์œผ๋กœ ์„ค์ •๋˜์–ด ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๊ฐ€ ๋™์‹œ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ—ˆ์šฉํ•œ๋‹ค.

๊ตฌํ˜„

์ž๋ฐ”์—์„œ๋Š” java.util.concurrent.Semaphore ํด๋ž˜์Šค๋ฅผ ํ†ตํ•ด ์„ธ๋งˆํฌ์–ด๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

Semaphore semaphore = new Semaphore(3); // ์ตœ๋Œ€ 3๊ฐœ์˜ ์Šค๋ ˆ๋“œ๊ฐ€ ์ ‘๊ทผ ๊ฐ€๋Šฅ

public void accessResource() {
    try {
        semaphore.acquire();
        // ์ตœ๋Œ€ 3๊ฐœ์˜ ์Šค๋ ˆ๋“œ๋งŒ ์ ‘๊ทผ ๊ฐ€๋Šฅ
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
    } finally {
        semaphore.release();
    }
}

 

๐Ÿค” ๋ฎคํ…์Šค๊ฐ€ ์žˆ๋Š”๋ฐ ์™œ ์„ธ๋งˆํฌ์–ด๋„ ์žˆ๋Š”๊ฑฐ์ง€?

๋ฎคํ…์Šค์™€ ์„ธ๋งˆํฌ์–ด ๋‘˜๋‹ค ๊ณต์œ  ์ž์›์— ๋Œ€ํ•œ ์ ‘๊ทผ์„ ์ œ์–ดํ•˜์ง€๋งŒ, ๊ฐ๊ฐ์˜ ์‚ฌ์šฉ ๋ชฉ์ ์ด ๋‹ค๋ฅด๊ณ  ๊ทธ ์ฐจ์ด์  ๋•Œ๋ฌธ์— ๋‘˜ ๋‹ค ํ•„์š”ํ•˜๋‹ค. 

1. ๋™๊ธฐ ์ ‘๊ทผ ์ œ์–ด์˜ ํ•„์š”์„ฑ

  • ๋ฎคํ…์Šค๋Š” ์ž์›์— ๋Œ€ํ•ด ํ•œ ๋ฒˆ์— ํ•˜๋‚˜์˜ ์Šค๋ ˆ๋“œ๋งŒ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•˜๋‚˜. ๋”ฐ๋ผ์„œ ํ•œ์ •๋œ ์ž์›์„ ๋…์ ์ ์œผ๋กœ ์‚ฌ์šฉํ•ด์•ผ ํ•  ๋•Œ ์ ํ•ฉํ•˜๋‹ค.
  • ์ผ๋ถ€ ์ž์›์€ ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๊ฐ€ ๋™์‹œ์— ์ ‘๊ทผํ•ด๋„ ๋ฌธ์ œ๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ๊ฐ€ ์žˆ๋‹ค. ์ด๋Ÿด ๋•Œ ์„ธ๋งˆํฌ์–ด๋ฅผ ์‚ฌ์šฉํ•ด ์ œํ•œ๋œ ์ˆ˜์˜ ์Šค๋ ˆ๋“œ๊ฐ€ ๋™์‹œ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋„๋ก ์ œ์–ดํ•˜๋Š” ๊ฒƒ์ด ๋” ํšจ์œจ์ ์ด๋‹ค.

2. ์ž์›์˜ ํšจ์œจ์  ์‚ฌ์šฉ

  • ๋ฎคํ…์Šค๋Š” ํ•œ ๋ฒˆ์— ํ•˜๋‚˜์˜ ์Šค๋ ˆ๋“œ๋งŒ ์ž์›์„ ์ ์œ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๊ฒฝ์šฐ์— ๋”ฐ๋ผ ๋น„ํšจ์œจ์ ์ผ ์ˆ˜ ์žˆ๋‹ค. ์ž์›์ด ์ถฉ๋ถ„ํžˆ ๋ณ‘๋ ฌ๋กœ ์ฒ˜๋ฆฌ๋  ์ˆ˜ ์žˆ๋Š”๋ฐ๋„ ํ•œ ์Šค๋ ˆ๋“œ์”ฉ ์ ‘๊ทผํ•˜๋„๋ก ์ œํ•œํ•˜๋ฉด ์‹œ์Šคํ…œ์˜ ํšจ์œจ์ด ๋–จ์–ด์ง„๋‹ค.
  • ์นด์šดํŒ… ์„ธ๋งˆํฌ์–ด๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ž์›์„ ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๊ฐ€ ๋™์‹œ์— ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜์–ด ์ž์›์˜ ํ™œ์šฉ๋„๋ฅผ ๋†’์ผ ์ˆ˜ ์žˆ๋‹ค. 
    • ์˜ˆ : ํ”„๋ฆฐํ„ฐ ์„œ๋ฒ„์—์„œ ์—ฌ๋Ÿฌ ๋Œ€์˜ ํ”„๋ฆฐํ„ฐ๋ฅผ ๋™์‹œ์— ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•˜๋ ค๋ฉด ์„ธ๋งˆํฌ์–ด๊ฐ€ ๋” ์ ํ•ฉํ•˜๋‹ค

3. ๋” ์œ ์—ฐํ•œ ๋™๊ธฐํ™” ์ œ์–ด

  • ๋ฎคํ…์Šค๋Š” ๋…์ ์  ์ ‘๊ทผ์„ ๋ณด์žฅํ•˜๋Š” ๊ฐ„๋‹จํ•œ ๋ฐฉ์‹์ด๋‚˜ ์‚ฌ์šฉ์ด ํŽธ๋ฆฌํ•˜์ง€๋งŒ, ์„ธ๋งˆํฌ์–ด๋Š” ์—ฌ๋Ÿฌ ์ž์›์˜ ๋™์‹œ ์ ‘๊ทผ์„ ๊ด€๋ฆฌํ•˜๋Š” ๋ฐ ์žˆ์–ด ํ›จ์”ฌ ๋” ๊ฐ•๋ ฅํ•œ ๋„๊ตฌ๊ฐ€ ๋œ๋‹ค.
  • ์„ธ๋งˆํฌ์–ด๋Š” ํŠน์ • ๋ฆฌ์†Œ์Šค์— ๋Œ€ํ•œ ์ ‘๊ทผ ๊ฐ€๋Šฅ์„ฑ์„ ๋™์ ์œผ๋กœ ์ œ์–ดํ•  ์ˆ˜ ์žˆ๋‹ค.
    • ์˜ˆ : ์ž์›์˜ ์ƒํƒœ์— ๋”ฐ๋ผ acquire(), release()๋ฅผ ํ†ตํ•ด ์ ‘๊ทผ ๊ฐ€๋Šฅ ์ˆ˜๋ฅผ ์กฐ์ ˆํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ ์ƒํ™ฉ์— ๋งž๊ฒŒ ์ž์›์„ ์œ ์—ฐํ•˜๊ฒŒ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.