8

ReentrantLock#tryLock(long,TimeUnit) の実装は、ロックを取得しようとすると何をしますか? スレッド A が のロックを実際に所有していて、myLockスレッド B が呼び出していると仮定するとmyLock.tryLock(10,SECONDS)、スレッド B はスリープ状態ですか、それとも待機状態ですか?

つまり、この 2 つの実装の違いは次のとおりです。

1.

while (true)
   try {
     if (readLock.tryLock())
       return;
     MILLISECONDS.sleep(5);
   }catch (InterruptedException e) {}

2.

 while (true)
   try {
     if (readLock.tryLock(5,MILLISECONDS))
       return;
   }catch (InterruptedException e) {}
4

5 に答える 5

3

まず第一に、ロックが解除された場合、2 番目は 5 ミリ秒未満待機しsleepます。そのため、飢餓の問題にさらされることは少なくなります。

次に、j.u.c.lパッケージは LockSupport#park メソッドを使用して、 ではなくスレッドを一時停止しますThread.sleep。そして、私が理解しているように、スレッドスケジューラーに違いがあるため、parkレイテンシーを下げることができますが、正確にどのようにsleep実装されているかはわかりません。

また、あなたのコードは意味がありません。まったく同じ効果がlock()メソッドによって達成される可能性があります。

于 2011-12-06T10:42:19.830 に答える
1

ロックを待っており、スレッドはスリープ状態です。

内部的には、tryLock(long, TimeUnit)メソッドがすぐにロックを取得できなかった場合、指定された時間だけ待機します。この時間が経過する前にロックが使用可能になると、すぐにロックが返されます。この場合、複数のスレッドがロックを要求している場合、ReentrantLockはランダムにスレッドを選択して次にロックを与えることに注意してください。この動作はtrue、コンストラクターで公平性の値を渡すことで変更できますnew ReentrantLock(true)

2 番目の例は、5 ミリ秒ごとにロックをチェックするだけです。スリープ中にロックが使用可能になり、ウェイクアップする前に別のスレッドに渡された場合、このスレッドはロックを取得できなくなります。

ロックを待機している多くのスレッドでこのコードを使用している場合、提供したいずれのソリューションも、すべてのスレッドがある時点でロックを取得することを保証しないことに注意してください。2 番目のコードは、5 ミリ秒が経過する直前に、別のスレッドによって狙われ続ける可能性があります。最初のコードはランダムですが、公平性の値が設定されていても、各スレッドは 5 ミリ秒ごとにその位置を放棄します。この場合は、タイムアウト値を増やしたほうがよいでしょう。適切な値は、すべてのスレッドがターンを取得するのにかかると予想される最大時間の約 2 倍です。

于 2011-12-06T10:44:56.097 に答える
1

技術的には、待機中のスレッドの状態に関して違いはありません。JavaDoc から:

ロックが別のスレッドによって保持されている場合、現在のスレッドはスレッドのスケジューリングの目的で無効になり、休止状態になります [...]

これは睡眠の場合と非常に似ていますが、実装を知らなければ確かなことは言えないと思います。

さて、この部分に注意してください:

[...] 次の 3 つのいずれかが発生するまで休止状態になります。ロックは現在のスレッドによって取得されます。また [...]

つまり、その間にロックが解放された場合、それを取得して戻ります。それ以外の場合、スリープ中は、スレッドが解放されていても、スレッドがロックを取得する機会はありません。

2 つのケースの間に現れる可能性があるもう 1 つの微妙な違いは、時限トライロックが ReentrantLock の公平性ポリシーに敏感であるという事実です。あれは:

このロックが公平な順序付けポリシーを使用するように設定されている場合、他のスレッドがロックを待機している場合、使用可能なロックは取得されません。

時間指定されていない trylock は不公平であることが知られており、他のスレッドが既にロックを待機している場合でも、ロックの取得に成功する可能性があります。

于 2011-12-06T10:42:37.537 に答える
0

ロックやその他の同時実行プリミティブの実装方法に関する優れたリファレンスについては、Shavit と Herlihy の優れたThe Art of Multiprocessor Programmingを参照してください。

于 2011-12-06T20:03:34.050 に答える
0

2番目のものは、すぐにロックしようとする最初のものとは異なり、ロックを取得するために5ミリ秒待機すると思います。したがって、スレッド B は、5 ミリ秒 (5 ミリ秒以内) にロックが取得されない場合に待機し、false を返します。通常、タイムアウトに 5 ミリ秒を設定しても違いはありませんが、この数値を増やすと鮮明な画像が得られます。

5 ミリ秒はタイムアウトで、ロックを 5 ミリ秒待機します。つまり、3 ミリ秒後にロックが使用可能になると、3 ミリ秒後に true が返されます。

于 2011-12-06T10:36:29.773 に答える