take() メソッドがキュー内の要素の数が 0 かどうかを判断するときに if ではなく while ループを使用する理由;
目が覚める理由は、put() メソッドが新しい要素を入れるためでもあり、他のスレッドはロックを取得できないため、当然要素を奪うことはできません。 、カウントは決して 0 ではありません。要素を取得するには、自由に dequeue() を実行してください。 作者が while を使用する意味がわかりません。
闭关修行中......
「notEmpty.await() メソッドが起動して戻るので、このスレッドはロックを取得しているはずです。」 この文は正しいです。
次のようなコードを書くとします:
1 つ明らかなことは、それが 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() にあることを確認する必要があり、それがエラーの原因となるということです。
return dequeue()
count != 0
notEmpty.await()
if(count == 0)
条件が満たされない場合にブロックするこの方法が wait()、await() while ループ内で使用されなければならない理由については、『Effective Java』第 2 版の第 69 条 (244 ページ) を参照してください。
wait()
await()
リーリー
そのため、コード内の現在のキューが空 (count == 0) の場合、 notEmpty.await(),这段代码对锁是有影响的,实际上底层上已经释放了锁,只是这个方法保证了被唤醒时一定又能够拿回锁(当有元素放入队列会调用notEmpty.signal()进行唤醒),那为什么需要使用while呢?因为insert后lock.unlock,未必notEmpty.await() の呼び出しによってすぐに起動されます。
notEmpty.signal()
lock.unlock
「notEmpty.await() メソッドが起動して戻るので、このスレッドはロックを取得しているはずです。」 この文は正しいです。
次のようなコードを書くとします:
リーリー1 つ明らかなことは、それが
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 ページ) を参照してください。リーリー
そのため、コード内の現在のキューが空 (count == 0) の場合、
の前に、削除メソッドを実行するスレッドを挿入できます。notEmpty.await()
,这段代码对锁是有影响的,实际上底层上已经释放了锁,只是这个方法保证了被唤醒时一定又能够拿回锁(当有元素放入队列会调用notEmpty.signal()
进行唤醒),那为什么需要使用while呢?因为insert后lock.unlock
,未必notEmpty.await()
の呼び出しによってすぐに起動されます。