Java同期ロックが順番に使用されるようにしますか?
-
05-07-2019 - |
質問
同期メソッドを介して1つのリストにアクセスする2つのスレッドがあります。
a)ランタイムに依存して、それぞれが試行した順序に基づいてメソッドへのアクセスを確実に受信するか、
b)VMは他のルールに従いますか
c)リクエストをシリアル化するより良い方法はありますか?
解決
いいえ、synchronizedは任意の順序でアクセスを許可します(JVM実装に依存します)。これにより、いくつかのシナリオでスレッドが枯渇することさえあります。
ReentrantLock (Java 5.0以降)で fair = true
オプションを使用します。 ( Lock lock = new ReentrantLock(true);
)
他のヒント
いいえ、同期メソッドへの2つの呼び出しが順番に発生することを確認することはできません。順序は指定されておらず、実装に依存します。
これは、 17.1ロック JLSのセクション。ロックを待機しているスレッドがアクセスを取得する順序については何も言われていないことに注意してください。
特定のメソッドが各スレッドから呼び出される順序に依存することはできません。スレッドが2つしかない場合は、yesになる可能性があります。しかし、3つのスレッドと1つのスレッドがすでにアクセスを取得している場合を想像してください。他の2つのスレッドがアクセスしようとすると待機し、そのうちの1つにアクセス権を付与できます。これは、このメソッドを呼び出した順序に依存しません。 したがって、順序に依存することはお勧めしません。
c)リクエストをシリアル化するより良い方法はありますか?
リストをキューとして使用している可能性はありますか?つまり、使用パターンは次のようになっていますか?
while (some condition) { synchronized(theList){ anItem = get and remove an element from theList } do some work with anItem }
その場合、 BlockingQueue
インターフェースを独自のロックスキームを使用する代わりに使用します。実装( ArrayBlockingQueue など)コード>
)公平性などの設定があります。
独自の強度を定義しない限り、常に同期をアプリサーバーまたはエンジンに残します
はい。
リストへのアクセスが1つの同期メソッドを介している場合、複数のスレッドからの同時リクエストはシリアル化されます。