2011-07-07 2 views

答えて

0

いいえ:外部と同期する必要はありません。

java.util.concurrentクラスのすべてのメソッドはスレッドセーフです。

+2

スレッドセーフであるとは、外部と同期する必要はありません。マップがどのような目的で使用されているかを知る必要があります。 (元のクラスの "threadsafety"はかなり不必要で不十分であったため、同じ理由で、Javaで導入された非同期コレクションクラス)。 – Thilo

+0

質問から利用情報を選ぶことはできません。確かにdownvoteの人には十分ではありません。 – Bohemian

+0

それはピーターの答えと同じレベルにそれを持って来るために "相対的なdownvote"でした。もし私が代わりにできるなら、私は彼を2度upvotedしていただろう。 – Thilo

0

私が知っている限り、すべての必要なロックがこのクラスで行われているので、あなたはいくつかの特定のことをしていない場合にそれを心配する必要はありません。 http://download.oracle.com/javase/1,5.0/docs/api/java/util/concurrent/ConcurrentHashMap.html

それは言う:

しかし、すべての操作は、検索操作がロック伴わないので、スレッドセーフであり、すべての防止方法で、テーブル全体をロックするための任意のサポートがないにもかかわらず、アクセス。

一般に、取得操作(getを含む)はブロックされないため、更新操作(putおよびremoveを含む)と重複する可能性があります。取得は、直前に完了した更新操作の結果を反映します。

これは、特定のアプリケーションで問題が発生していない場合でも、気にする必要はありません。

1

コレクションをロックする必要がある場合は、外部同期のみが必要です。コレクションは内部ロックを公開しません。

ConcurrentMapにputIfAbsentが設定されていますが、オブジェクトの作成に費用がかかる場合は、これを使用したくない場合があります。

final ConcurrentMap<Key, Value> map = 

public Value get(Key key) { 
    // allow concurrent read 
    return map.get(key); 
} 

public Value getOrCreate(Key key) { 
    // could put an extra check here to avoid synchronization. 
    synchronized(map) { 
     Value val = map.get(key); 
     if (val == null) 
      map.put(key, val = new ExpensiveValue(key)); 
     return val; 
    } 
} 
1

はい、いいえ。あなたがやっていることに依存します。 ConcurrentHashMapは、すべてのメソッド(getやputなど)に対してスレッドセーフです。ただし、非アトミック操作の場合はでなく、スレッドセーフです。ここでの例では、非アトミック動作を行う方法であって

public class Foo { 
    Map<String, Object> map = new ConcurrentHashMap<String, Object>(); 

    public Object getFoo(String bar) { 
     Object value = foo.get(bar); 
     if (value == null) { 
      value = new Object(); 
      map.put(bar, foo); 
     } 
     return value; 
    } 
} 

ここで欠陥はgetFooを呼び出す2つのスレッドが別のオブジェクトを受信することが可能であることです。 intのような簡単なデータ構造やデータ型を扱う場合、非アトミック操作では常に外部同期が必要です。 AtomicIntegerやConcurrentHashMapなどのクラスは、いくつかの一般的な操作をスレッドセーフにしますが、上記のgetFooのようなチェック・セット・セット操作に対しては保護しません。

関連する問題