CH04 - Locks

  • Dead Lock 예제 StackOverflowarrow-up-right

    • functionOne()에서 functionTwo()를 호출 순간 dead lock

    • 이유: the thread would have to wait for the lock...which it holds itself.

public synchronized void functionOne() {

    // do something

    functionTwo();

    // do something else

    // redundant, but permitted...
    synchronized(this) {
        // do more stuff
    }    
}

public synchronized void functionTwo() {
     // do even more stuff!
}

Dead Lock 해결방법 - ReentrantLock

  • Reentrant Mutex (a.k.a, Recursive Mutex)

    • 동일한 쓰레드에서 여러번 락을 걸 수 있음

    • lock 개수만큼 unlock을 해야된다.

      • 예제에서, addPotato() 에서 addPotato()으로 갈때 각 메소드에서 lock 2번과 unlock을 2번한다.

  • 자바의 Lock을 구현한 3개 클래스

    • ReentrantLock

    • ReentrantReadWriteLock.ReadLock

    • ReentrantReadWriteLock.WriteLock

    • 전부 이름에 ReentrantLock이 포함됨. 즉, 자바에선 non-ReentrantLock는 지원안함.

  • 코드해석

    • addPotato()에 동일 쓰레드에 있는 addGarlic()을 호출하여, 데드락 위험이 있지만, ReentrantLock 사용하여 해결

Try Lock 사용 유무 비교

  • Mutex (pencil) 를 얻으려고 스탠다드 Lock 사용 경우

  • 아래 코드 "★★★★여기★★★★★" 를 보면, 다른 사람이 적는 시간 3초를 기다리게 된다.

    • 효율적으로 가려면, Thinking 시간이 1초이기 때문에 3번 Thinking 해서 다른 사람의 Writing이 끝나면 적으면, 더 빨리 끝낼 수 있다.

  • Try Lock 사용한 경우

    • Lock.tryLock()

    • 속도가 빠르다. (걸린시간 결과 확인하기)

    • 이유

      • pencil.tryLock() 을 보면

      • try 해보고, 이미 lock이 걸려있으면, return false 한다.

  • 교훈

    • 다른 쓰레드가 사용중인 자원이 필요할 경우, 마냥 기다리지 말고, 다른일을 먼저 처리해도 되면 그걸 하고 와서 다시 기다려보자.

ReentrantReadWriteLock

  • Reader-Writer Lock 특징

    • Shared Read: 여러 쓰레드가 같이 읽을 수 있음

    • Exclusive Write: 한 쓰레드만이 쓸 수 있음

  • 보통은 일반적은 DB 처럼 Read가 많음. (Write많으면, Reader-Writer Lock 쓸 필요 없음.)

  • 코드 해석

    • 10명의 Reader와 2명의 Writers가 캘린더를 공유한다.

    • Reader-Writer Lock을 사용하지 않았을때 나타나는 문제점을 본다.

  • Read와 Writer Lock을 분리한다.

  • 위 두개 결과 비교

  • 첫번째 코드 결과

    • 문제점: 한 reader가 읽는 동안 다른 reader도 읽을 수 있어야 하는데, 쓸데없이 한 리더가 자원을 계속 점유한다.

    • 궁금: 왜 7번보다 훨씬 많이 나오지...? 예를들어, 첫번째 "Reader-2 sees that today is Sun"이게 30번은 나옴..

  • 두번째 코드 결과

    • 결과 값이 짧다.

    • Reader가 고르게 자원을 공유하는 것을 확인할 수 있다.

    • getReadLockCount()를 통해 현재 같이 read 중인 (=같이 Lock를 holding 중인) 다른 쓰레드를 확인할 수 있다.

QUIZ

  • How many threads can possess the ReadLock while another thread has a lock on the WriteLock?

    • 0

  • What is the maximum number of threads that can possess the WriteLock of a ReentrantReadWriteLock at the same time?

    • 1

  • What is the maximum number of threads that can possess the ReadLock of a ReentrantReadWriteLock at the same time?

    • no limit

  • Which of these scenario describes the best use case for using a ReadWriteLock?

    • Lots of threads need to both and modify the value of a shared variable.

    • Only a few threads need to both and modify the value of a shared variable.

    • Lots of threads need to read the value of a shared variable, but only a few thread need to modify its value. (답)

    • Lots of threads need to modify the value of a shared variable, but only a few thread need to read its value.

    • What happens when a thread calls Java's tryLock() method on a Lock that is NOT currently locked by another thread?

      • The method immediately returns true

    • What is the difference between the tryLock() and the regular lock() method in Java? 다시

      • tryLock() includes built-in error handling so you do not need a separate try/catch statement

      • tryLock() will continuously try to acquire the lock if it is already taken by another thread

      • tryLock() is a non-blocking version of the lock() method (답)

    • Why is the tryLock() method useful?

      • It enables a thread to execute alternate operations if the lock it needs to acquire is already taken. (답)

      • If multiple threads try to acquire a lock simultaneously, the tryLock() method will randomly pick one to succeed.

      • It enforces fairness among multiple threads competing for ownership of the same lock.

      • It includes built-in protection against common locking errors.

    • Which statement describes the relationship between Lock and ReentrantLock in Java?

      • ReentrantLock is a class that implements the Lock interface.

    • How many times must a thread unlock a ReentrantLock before another thread can acquire it?

      • as many times as that thread locked it

    • A ReentrantLock can be locked _____. 다시

      • once by multiple threads at the same time

      • multiple times by different threads

      • multiple times by the same thread (답)

Last updated