찾다

 >  Q&A  >  본문

java - ArrayBlockingQueue에서 소스 코드에 대한 설명을 찾고 있습니다.

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

으아악

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

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

阿神阿神2737일 전871

모든 응답(2)나는 대답할 것이다

  • 漂亮男人

    漂亮男人2017-05-27 17:43:19

    "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
  • 黄舟

    黄舟2017-05-27 17:43:19

    으아아아

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

    전에 제거 메소드를 실행하기 위해 스레드를 삽입하는 것이 가능할 수도 있습니다.

    회신하다
    0
  • 취소회신하다