1. ホーム
  2. java

[解決済み] Java同期ブロックとCollections.synchronizedMapの比較

2023-05-05 11:34:47

質問

以下のコードで synchronizedMap ?

public class MyClass {
  private static Map<String, List<String>> synchronizedMap = Collections.synchronizedMap(new HashMap<String, List<String>>());

  public void doWork(String key) {
    List<String> values = null;
    while ((values = synchronizedMap.remove(key)) != null) {
      //do something with values
    }
  }

  public static void addToMap(String key, String value) {
    synchronized (synchronizedMap) {
      if (synchronizedMap.containsKey(key)) {
        synchronizedMap.get(key).add(value);
      }
      else {
        List<String> valuesList = new ArrayList<String>();
        valuesList.add(value);
        synchronizedMap.put(key, valuesList);
      }
    }
  }
}

私の理解では、同期ブロックは addToMap() を他のスレッドから呼び出されないようにするために remove() または containsKey() への呼び出しを通過する前に put() を呼び出す前に、同期ブロックは必要ありません。 doWork() の同期ブロックに他のスレッドが入ることはできないからです。 addToMap() の前に remove() でMapを作成したため Collections.synchronizedMap() . これは正しいのでしょうか? もっといい方法はないでしょうか?

どのように解決するのですか?

Collections.synchronizedMap() は、マップ上で実行したい各アトミック操作が同期されることを保証します。

しかし、マップ上で2つ(またはそれ以上)の操作を実行する場合は、ブロック内で同期させる必要があります。 ですから、あなたは正しく同期しています。