1

私はConcurrentHashMapサーブレットコンテキストに保存し、マップ内のデータは同時に変更されます。サーブレットコンテキストはスレッドセーフではありませんが、ConcurrentHashMap(書き込み用に)安全であることを知っています。この場合、同期構築を使用する必要がありますか?

 synchronized (context) {
   ConcurrentHashMap messages =(ConcurrentHashMap)context.getAttribute("map");
   String mes  = messages.get("id");  // can be changed by another thread?
   messages.put("id",mes +"changed by thread 1");   
  }
4

3 に答える 3

1

申し訳ありませんが、問題がわかりません。この例では、「messages」はローカル変数であり、すべてのスレッドに 1 つあります。あなたは「メッセージ」を共有していません

「コンテキスト」から読み取るときに唯一の問題が発生する可能性があるため、その読み取りを同期するだけで済みます

ConcurrentHashMap messages = null;
synchronized (context) {
    ConcurrentHashMap messages =(ConcurrentHashMap)context.getAttribute("map");
}
String mes  = messages.get("id");  // can be changed by another thread?
messages.put("id",mes +"changed by thread 1");   

しかし、最善のことはそれを避けることです。読み取りフォームのコンテキストでの同期をどのように回避しますか? 簡単に言えば、コンテキストで書いたり、初期化プロセスでのみ行ったりしてはいけません。

于 2012-08-02T16:22:28.857 に答える
1

ServletContext の初期化時に Map を保存する場合は、コンテキストが閉じられるまでマップを削除しないため、同期して取得する必要はありません。

Map が同時実行を処理するかどうかは問題ではありません。後者の場合、マップ上で同期する必要がありますが、同時実行を処理するものを使用しているため、それを行う必要さえありません。

于 2012-08-02T13:37:08.813 に答える
0

Map への参照を保持した後に Map に加えられる変更が心配な場合は、Map のコピーを返すメソッドでコードをラップすることができます。その場合、コピー時からのマップのスナップショットを保持します。

変更を完全に同期したい場合は、Collections.syncrhonizedMap(...) を使用できます。

于 2012-08-02T13:54:19.117 に答える