Thread.sleep()
ロックを保持していることは知っていますが、ロックをObject.wait()
解放します。yield
実際に実装していると言う人もいますsleep(0)
。これは、yield がロックを解放しないということですか?
別の質問です。現在のスレッドがロックを取得し、 を呼び出したとしanotherThread.join()
ます。現在のスレッドはロックを解放しますか?
Thread.sleep()
ロックを保持していることは知っていますが、ロックをObject.wait()
解放します。yield
実際に実装していると言う人もいますsleep(0)
。これは、yield がロックを解放しないということですか?
別の質問です。現在のスレッドがロックを取得し、 を呼び出したとしanotherThread.join()
ます。現在のスレッドはロックを解放しますか?
javadoc にオブジェクトのモニター ( などObject.wait()
) が記載されていない限り、ロックは引き続き保持されると想定する必要があります。そう:
これは、yield がロックを解放しないということですか?
はい。
現在のスレッドはロックを解放しますか?
いいえ。
sleep
スレッドを待機状態にしyield
、スレッドをレディ プールに直接返します。(したがって、スレッドが譲歩した場合、実行中からレディ プールに直接移動し、待機することなくスケジューラによって再び選択される可能性があります。) どちらもロックとは何の関係もありません。
Java言語仕様から:
Thread.sleep は、現在実行中のスレッドを、システム タイマーとスケジューラの精度と精度に従って、指定された期間スリープ (一時的に実行を停止) させます。スレッドはどのモニターの所有権も失うことはなく、実行の再開はスケジューリングと、スレッドを実行するプロセッサーの可用性に依存します。
Thread.sleep も Thread.yield も同期セマンティクスを持たないことに注意することが重要です。特に、コンパイラは、Thread.sleep または Thread.yield を呼び出す前に、レジスタにキャッシュされた書き込みを共有メモリにフラッシュする必要はなく、Thread.sleep または Thread を呼び出した後に、レジスタにキャッシュされた値を再ロードする必要もありません。 。収率。
たとえば、次の (壊れた) コード フラグメントでは、 this.done が非揮発性ブール フィールドであると想定しています。
while (!this.done) Thread.sleep(1000);
コンパイラは、フィールド this.done を 1 回だけ自由に読み取り、ループの各実行でキャッシュされた値を再利用できます。これは、別のスレッドが this.done の値を変更したとしても、ループが終了しないことを意味します。