web-dev-qa-db-ja.com

同じデータを共有/アクセスする複数のスレッドの問題

私は、Java内の複数のスレッドがデータにアクセスまたは共有するタイミングを調査しています。そして次のような問題を調べます:

  • スレッド干渉
  • メモリの一貫性
  • デッドロック
  • 飢餓

これから、これらの問題を解決するソリューション。

これまでのところ、これらの問題を修正するために私が見つけたのは、同期方法を使用することだけです。同期方法を使用する他の方法はありますか?

私は、Sunからこの情報のほとんどを見つけましたJavaチュートリアル。詳細についての推奨事項はありますか?

6
Frank_B

明示的な同期を必要としないテクニックはたくさんあります。

たとえば、すべてのデータを各スレッドに対してローカルに保ち、メッセージの受け渡しのみを介して通信する場合、同期はメッセージの送信と待機によって暗黙的に実行されます。

メッセージパッシング システムには ユニファイドメモリアーキテクチャ を必要としないため、拡張性が非常に高いという利点があります。たとえば、デッドロックを検出して防止するための正式な手法があります- Communicating Sequential Processes(CSP) は、そのようなシステムについて正式に推論するのに役立ちます。

別のオプションは、不変のデータセットの使用です。何も変更できない場合は、同期する必要はありません。一度に複数のスレッドが書き込みを試みる可能性はないためです。

それらを組み合わせることもできます。1つのプロセスが不変の共有メモリデータセットを作成する場合、メッセージを使用してそのデータのコンシューマーにポインターを渡すことができます。

最後に、より高いレベルの抽象化の観点から考えることができます。 BlockingQueue from Java.util.concurrent を使用してプロセスを結合します。キューの実際の実装について考える必要はありません。1つのプロセスで作成するだけです。そして別のものでそれらを消費します。

Semaphor などのプリミティブを使用すると、synchronizedよりも低い抽象化レベルがあります。

全体として、学習するのは豊かで深い領域であり、各手法の長所と短所を理解することで、より優れたプログラマーになる可能性があります。

10
Mark Booth

共有データに不変オブジェクトを使用することを検討することをお勧めします。可能な限り、変更されたデータへのアクセスを1つのスレッドに制限するようにしてください。

いくつかの利点:

  • 共有データは変更できないため、メモリの一貫性やスレッドの干渉に関する問題はありません
  • 同期メソッドを使用する必要はありません

考えられる欠点:

  • 不変オブジェクトを更新できません
  • 更新するのではなく新しいコピーを頻繁に作成する必要がある場合は効率が低下します
4
user39685

Java.util.concurrentパッケージ of Java SEをチェックしてください。同期を維持するためのオプションがたくさんあります。それでもうまくいかない場合Google Guavaには、このパッケージに興味深い追加機能がいくつかあります。

4
Dibbeke

アトミック変数を確認しましたか?

http://www.ibm.com/developerworks/Java/library/j-jtp11234/

記事の著者であるBrian Geotzは、非常に優れた本「Java Concurrency in実際」も書いています。

1
Jaydee