私はいくつかのプライベートハッシュマップを宣言し、いくつかの方法でそれらを更新するスプリングコントローラをコーディングしています。もちろん、私は同時アクセスの問題を認識しているので、私はこれらの問題を回避する最も簡単な方法を使用しています: "同期化された" Javaスレッドセーフ機能。しかし私は自分のメソッドを同期するべきか、または安全に更新する必要があるハッシュマップだけを同期するべきかどうか疑問に思っていました。これらのメソッドは同等ですか?私はアプリケーションの同じ動作をしますか?Javaスレッドセーフ、データ競争と良い実装
答えて
myHashMap変数がプライベートで、myControllerメソッドを介してのみアクセスできる場合は、メソッドを同期する必要があります。別の方法として、メソッドを同期させるとスレッドセーフになりますが、同期ブロック/メソッドを使用せずにmyHashMap変数に直接アクセスすると、ロックを覆すことができます。
さらに簡単に言えば、あなたは一度に1人の人を許可するドアがある部屋があれば、一度に部屋に1人しかいないでしょう...しかし、部屋に窓を置くと、あなたはまだ窓からの部屋。 :)
EDIT:詳しく説明します。このメソッドにsynchronizedをキーワードとして設定することで、メソッド全体のクリティカルセクションが作成されます。つまり、メソッド呼び出しの終了からそのオブジェクトで実行できることは他にありません。クローズブロックを使用することで、クリティカルセクションを必要に応じて出入りすることができます。 100行のメソッドがあるとします。共有リソースを使用するために必要な10行について、メソッドにsynchronizedを置くと、オブジェクトは100行全体に対してロックされますが、ロックを10行だけに置くとあなたが必要とする行は、10行にはクリティカルセクションしかありません。
あなたがいる状況はすべてです。あなたが与えた例では、全く違いはありません。
大きな違いがあります。同じオブジェクトでは同期していません。ここでは問題にはならないように見えるかもしれませんが、その例は明らかに不完全なので、言い難いです。 – Bruno
合意。簡単に質問に答えるために、回答は同じではありません。たとえば、myControllerオブジェクトをロックしている最初の例では、2番目にhashmapオブジェクトをロックしています。 –
あなたの最後のパラグラフでは、「他に何もそのオブジェクトを実行することはできません」ということは、「同じインスタンスオブジェクト*上で同期するものは何も実行できません」ということを明確にするのに非常に役立つと思います。 'synchronized'ブロックが何か他のことが起こるのを止めるのに対し、' synchronized'ブロック/メソッド(同じモニター上)で起こる他のアクションだけをブロックするのは、初心者の間違いです。 –
これらの方法は同等ではありません。方法に
ので、this
に同期化:this
はmyController
のインスタンスであり、ここで
public updateMyHashmap(){
synchronized(this) {
myHashMap.add(value);
}
}
:
public synchronized updateMyHashmap(){
myHashMap.add(value);
}
と等価です。 (サイドノート:Javaでは大文字でクラス名を開始することをお勧めします)。
静的メソッドから非静的メンバー(myHashMap
)にアクセスしているため、2番目の方法が正しくないため、コンパイルしないでください。
静的ではないと仮定すると、myController
インスタンスではなくハッシュマップで同期します。
あなたが同期したいものは、この同期ブロックで何をしたいかによって決まるでしょう(例えば、value
はどこから来たのでしょうか?操作はmyController
インスタンスを使用して同期する必要があります)。
同期の問題の詳細については、Java Concurrency in Practiceをお読みください。
私はConcurrentHashMapを使用し、手動でアクセスを同期させないでください。
メソッドを静的にすることは、ここではあまり役に立ちません。特に、同期するオブジェクトが必要なので、これは通常これです。
staticメソッドを 'synchronized'として宣言すると、メソッドを宣言するクラスの' Class'オブジェクトと同期します。したがって、同期するデフォルトのオブジェクトが不足する心配はありませんが、メソッドを静的にすることはスレッドセーフの問題とは無関係です。 –
@Jilles:java docによると: "ただし、すべての操作がスレッドセーフであっても、検索操作はロックを伴わず、すべてのアクセスを阻止する方法でテーブル全体をロックするためのサポートはありません。" – Zamboo
@Zambooなぜあなたは*それを望んでいますか?すべてのアクセスを阻止するロックが必要な達成しようとしているのは何ですか? –
この2つは異なるものですが、同じ種類の目的を達成するために使用できます。
だから、私はあなたが今簡単にこれらの2つの戦略の違いを見ることができると思い
public updateMyHashmap(){
//Some code here
System.out.println("Inside method")
synchronized(this) {
myHashMap.add(value);
}
}
この方法では今、ここに
//Here you are locking your method
public synchronized updateMyHashmap(){
System.out.println("Inside method");
//some code
myHashMap.add(value);
}
を参照してください。それはあなたがしたいことに依存し、それに応じてあなたはそれらのどれかを選ぶことができます。
ロックしたいオブジェクトを同期することをお勧めします。
私がしたいことは、ハッシュマップデータを正しく更新させるために「ちょうだい」です:ハッシュマップの更新プロセスが開始されると(それはいくつかのメソッドが呼び出すことができます...)、その後、他のスレッドのデータ – Zamboo
- 1. データ競争と安全な発行
- 2. スレッドセーフな実装
- 3. 約束と競争条件
- 4. 'スレッドセーフな'リンクリストの実装
- 5. スレッドセーフなロギングクラスの実装
- 6. ビルダーパターンのスレッドセーフな実装
- 7. 循環バッファのスレッドセーフ実装
- 8. スレッドセーフなスレッドと非スレッドセーフなカウンタの実装
- 9. なぜデータ競争がないのですか?
- 10. 良いhashCode()実装
- 11. ウィンザーとasp.net MVCシングルトン競争条件
- 12. Cの競争条件
- 13. NServicebusサガ競争条件
- 14. 春の競争条件コントローラ
- 15. スレッドセーフな辞書実装でデータ競合が発生するのはなぜですか?
- 16. Oracle Java KeyStoreの実装はスレッドセーフですか?
- 17. スレッドセーフJavaでシングルトンパターンを効率的に実装する方法は?
- 18. Java StringBuilderとスレッドセーフ
- 19. 大きな行列とベクトルの各列間の相関のメモリと時間効率の良い競争
- 20. MaxMindのGeoIP C実装スレッドセーフですか?
- 21. C++でのスレッドセーフなシングルトン実装
- 22. 初期化のNSThreadスレッドセーフ実装。
- 23. .NET上のスレッドセーフなブロッキングキューの実装
- 24. 良いオープンソースのJava SE JTA TransactionManager実装は何ですか?
- 25. Intel Inspectorはスピンロック実装のデータ競合を報告します
- 26. 見た目の競争状態ローディングコンテンツ
- 27. オペレーティングシステムの設計競争条件
- 28. Java 6 JAXB/JAXP/SAAJの参照実装がXercesと競合する
- 29. 競争相手のバナーのローテーションについては誰でも良いドキュメントを知っていますか?
- 30. Javaツリーのデータ構造の実装
ConcurrentHashMapを代わりに使用している理由は何ですか? –
@Jon:Jillesへの返信を参照してください。 – Zamboo