2013-10-07 9 views
5

ハッシュテーブルが同期されているため、ハッシュテーブルはスレッドセーフです。このコードスニペットを検討してくださいハッシュテーブルとJavaでの同期

if(!hashtable.contains(key)){ 
hashtable.put(key,value); 
} 

ハッシュテーブルの操作が同期されていない可能性があります。たとえば、Thread t1がhastableにアクセスしてキーをチェックし、同時にThread t2がt1がputを実行する前にキーをチェックするとします。今度は2つのスレッドがifブロックの内側にあり、キー値の上書きが発生します。

同期ブロックが必要です。

synchronized { 
if(!hashtable.contains(key)){ 
    hashtable.put(key,value); 
    } 
} 

この理解は正しいですか?またはhastablesの上で実行される操作上のhastables安全です。私はこれを読んでいる間、この疑いを持っていますpost on race condition

+0

はい正しいです。 – SJuan76

答えて

9

あなたは​​ブロックが必要であることは間違いありません。 Hashtable'sのメソッドは​​ですが、​​ブロックの外側にある複数のメソッドを呼び出すと、まだ競合する可能性があります。ビルトイン同期は、たとえば2つのスレッドが同時にputを呼び出すときの問題を防ぎます。あなたはまた、ConcurrentHashMap

3

Hashtableメソッドに見たいと思うかもしれません

は同期、しかし、それは唯一の競合状態に対してメソッドレベルの保護を提供しています。 (Hashtable —と異なるのはHashMap —です。複数のスレッドが同時にデータを変更しようとすると、内部的に破損することはありません)。Hashtableはスレッドセーフです。

HashtableConcurrentHashMapどちらを使用すると、マルチステップの操作を実行しているときに必要なものを通常*で、より高いレベルの同期を提供します。とにかく外部​​ブロックが必要なので、Hashtableではなく、より低いオーバーヘッドのHashMapを使用することもできます。

  *ジェフ・ストーリーが指摘するように、ConcurrentHashMapはあなたのコードでやっているまさにんputIfAbsent方法があります。他のマルチステップ操作では、ConcurrentHashMapには、アトミックに必要な処理を行うメソッドがある場合とない場合があります。

+1

'ConcurrentHashMap'は、鍵の包含を原子的にチェックし、存在しなければそれを置く' putIfAbsent'メソッドを持っています。 –

+0

@JeffStorey - はい、それを忘れました。ありがとうございました。私はそれに応じて私の答えを更新します。それでも、他のマルチステップ動作では、外部同期が必要になることがあります。 –