java - ArrayBlockingQueue에서 소스 코드에 대한 설명을 찾고 있습니다.
阿神
阿神 2017-05-27 17:41:19
0
2
879

큐의 요소 수가 0인지 판단할 때 take() 메서드가 if 대신 while 루프를 사용하는 이유는 무엇인가요?

으아악

깨어나는 이유도 put() 메소드가 새로운 요소를 넣는데 다른 스레드는 잠금을 얻을 수 없기 때문에 당연히 요소를 빼앗을 수 없기 때문입니다. 따라서 이때 잠금을 얻은 스레드의 경우 count는 확실히 0이 아닙니다. 요소를 얻으려면 dequeue()를 자유롭게 실행해야 합니다.

작성자가 while을 사용하여 무엇을 의미하는지 모르겠습니다.

阿神
阿神

闭关修行中......

모든 응답(2)
漂亮男人

"notEmpty.await() 메서드가 깨어나서 반환되므로 이 스레드는 잠금을 획득한 것이 틀림없습니다." 이 문장은 정확합니다.

당신이 작성한 코드가 다음과 같다고 가정해보세요:

으아악

한 가지 분명한 점은 return dequeue() 之前需要满足的一个条件是 count != 0。我们假设 线程A 此时拿到了 lock,那么 线程A 的 notEmpty.await() 此时便会停止阻塞,准备向下执行 return dequeue()。但是假设在竞争激烈的条件下,线程A 拿到 lock 之后,准备执行下一条 JVM 指令的时候,线程B 此时抢占了 lock,然后继续向下执行 return dequeue(),刚好使得 count 变为了 0;而此时因为写的只是 if(count == 0),那么线程 A 在拿到 lock 之后,还是会继续向下执行 return dequeue()에 있는지 확인해야 하며 이로 인해 오류가 발생한다는 것입니다.

wait()await()조건이 충족되지 않을 때 차단하는 방법while 루프에서 사용해야 하는 이유는 "Effective Java" 제2판 69조(244페이지)를 참조하세요.

黄舟

으아아아

따라서 코드에서 현재 대기열이 비어 있으면(개수==0) 호출 notEmpty.await(),这段代码对锁是有影响的,实际上底层上已经释放了锁,只是这个方法保证了被唤醒时一定又能够拿回锁(当有元素放入队列会调用notEmpty.signal()进行唤醒),那为什么需要使用while呢?因为insert后lock.unlock,未必notEmpty.await()이 즉시 활성화됩니다.

전에 제거 메소드를 실행하기 위해 스레드를 삽입하는 것이 가능할 수도 있습니다.
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿