notify()와 informAll()의 미묘한 차이
notify()와 informAll()의 주요 차이점은 깨어나는 대기 스레드의 수(하나 대 전체)는 또 다른 질문을 제기합니다.
왜 하나의 스레드가 항상 객체 잠금을 다시 획득합니까?
일반적인 경우, inform() 및 informAll()은 잠금을 다시 획득하기 위해 선택될 대기 스레드를 지정하지 않습니다. JVM 또는 시스템 스레드 스케줄러가 이를 선택하며 이는 비결정적일 수 있습니다.
notifyAll()의 필요성
그러나 특정 시나리오에서는 inform()을 사용합니다. 다음 예에서 설명한 것처럼 교착 상태로 이어질 수 있습니다.
생산자/소비자 클래스 통지()
public class ProducerConsumer { private final int MAX_SIZE = 1; // Buffer size private List<Object> buf = new ArrayList<>(); public synchronized void put(Object o) { while (buf.size() == MAX_SIZE) { wait(); } buf.add(o); notify(); } public synchronized Object get() { while (buf.size() == 0) { wait(); } Object o = buf.remove(0); notify(); return o; } }
교착 상태 시나리오:
결과적으로 세 스레드 모두 무기한 대기하여 교착 상태가 발생합니다.
해결책: informAll()
이 교착 상태를 해결하려면 생산자/소비자 코드에서 inform() 대신에 informAll()을 사용해야 합니다. 이렇게 하면 대기 중인 모든 스레드가 활성화되어 교착 상태가 방지됩니다.
권장 사항:
대부분의 시나리오에서는 잠재적인 교착 상태를 방지하기 때문에 informAll()이 선호되는 방법입니다. 특정 시나리오에서 하나의 특정 대기 스레드만 깨워야 하는 경우에는 inform()을 주의해서 사용할 수 있습니다.
위 내용은 한 스레드가 통지() 또는 통지All() 후에 항상 객체 잠금을 다시 획득하는 이유는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!