2017-01-03 4 views
2

Java에서 스레드 t2이 다른 스레드에서 현재 사용중인 동기화 된 잠금을 얻으려고 시도하면 t1, t2은 실행 가능에서 차단으로 전환됩니다. 옳은? ReentrantLock s는 어떨까요?스레드 상태, 잠금 및 조건

t1 스레드가 잠금을 사용하여 끝나면 t2이 자동으로 실행 가능으로 다시 전환 되나요? 아니면 notifyAll()을 사용해야합니까? 어떤 조건없이 ReentrantLock을 사용하면 어떨까요? 조건을 사용하지 않는 경우 스레드 t2에 실행 가능으로 다시 전환해야한다고 알리는 방법은 무엇입니까? 조건없이 재진입 가능한 자물쇠를 사용하는 것이 현명한가요?

이 질문에 이미 답변 (찾을 수 없음)했다면 나에게 연결해 주시면 감사하겠습니다.

답변

4

차단 된 상태와 대기 상태가 혼동 스럽기는합니다. Blocked는 스레드가 잠금을 얻으려고 시도 중이므로 멈출 수 없다는 것을 의미합니다. 대기한다는 것은 스레드가 휴면 상태임을 의미합니다. 그것은 알림을받을 때까지 또는 대기 시간 (시간 초과 값, 또는 가짜 웨이크 업으로 호출 된 경우)에서 다시 돌아올 때까지 기다리고 있습니다.

잠금을 사용할 수있게되면 OS 스케줄러는 차단 된 스레드가 잠금을 가져야하는지 결정해야합니다. 잠금을 얻기 위해 선택한 스레드가 실행 가능하게됩니다.

그래서 알림은 차단 된 스레드가 아니라 대기중인 스레드와 관련이 있습니다. 잠금을 가지고 있지만 그것이 진행할 수 없다는 것을 알아 낸 스레드는 기다리고있는 조건이 사실이 아님을 발견하면 그 잠금에 대한 대기를 호출하여 잠금을 해제하고 휴면 상태로 전환 할 수 있습니다. 알림을 사용하여 스케줄러가 잠금 대기중인 스레드를 깨우도록 지시합니다. 스레드가 깨어나면 wait 메소드를 종료하기 전에 이전에 해제 한 잠금을 다시 획득해야합니다.

ReentrantLock의 기본 동작은 재진입 잠금을 사용하여 여러 조건을 가질 수 있다는 점을 제외하고는 고유 잠금과 유사합니다. ReentrantLock에는 별도의 호출 방법 (대기 및 알림 대신 기다리고 신호)이 있습니다. 스레드가 기다리고 알림을 얻고 다른 조건을 사용하여 스레드가 관련 조건에서만 대기하게하려면 ReentrantLock에서 조건을 사용합니다.

+0

그는 "대기 중"이라는 용어를 "실행 가능"이라고 생각합니다. –

+0

혼란은 내가 읽고있는 책 (Cay S. Horstmann의 Object-Orinted Design and Patterns)에서 비롯된 것입니다. 이 책에서 다음 내용을 읽을 수 있습니다 [스크린 샷] (http://imgur.com/a/qYm36). 이게 단순한가요, 아니면 제가 빠진 것이 있습니까? –

+0

@erikp는 단순화 된 것처럼 보입니다. [JavaDocs of Thread.State] (https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.State.html) – Hulk

0

스레드 t2가 다른 스레드 t1에서 현재 사용중인 잠금에서 동기화를 시도하는 경우 - 예를 들어 t1이 이미 동일한 잠금의 동기화 된 블록에있을 때 동기화 된 블록을 입력하려고 시도하면 t2가 차단됩니다 , 예. ReentrantLock 클래스를 포함한 재진입 잠금에도 해당됩니다. Java에서 기본 잠금이 재진입된다는 점에 유의해야합니다 (자세한 내용은 나중에 설명).

t1이 동기화 된 블록을 종료하는 것과 같이 기본 잠금을 해제하면 t2가 차단 해제됩니다. 이것이 언어의 특징입니다. 그러나 ReentrantLock을 사용하는 경우 잠금을 보유하는 스레드는 ReentrantLock.lock()을 호출하여 잠금을 해제해야하는 것처럼 명시 적으로 ReentrantLock.unlock()을 호출하여 잠금을 해제해야합니다.

"재진입 성"은 단일 스레드가 스레드 간의 상호 작용이 아닌 동기화 된 블록을 "다시"시작할 수 있는지 여부를 나타냅니다. 재진입 잠금은 이미 잠금을 유지하고있는 스레드에 의해 다시 잠길 수 있습니다. 비 허용 잠금은 할 수 없습니다. Java에서 단일 스레드가 재진입 성 잠금을 두 번 이상 획득하는 경우 잠금을 대기중인 다른 스레드가 차단 해제되기 전에 동일한 횟수만큼 잠금을 해제해야합니다. 기본 잠금의 경우, 중첩 된 동기화 블록에서 자연스럽게 발생하며 가능하면 다른 함수 호출 수준에서 발생합니다.