线程安全的队列映射

Rob*_*ain 1 java queue multithreading concurrenthashmap

我想实现一个线程安全的队列映射。

我打算从一张空地图开始。如果该键不存在,我想用新的队列创建一个新的映射条目。如果该键确实存在,我想添加到队列中。我建议的实现如下:

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;

public class StackOverFlowExample {

    private final Map<String, ConcurrentLinkedQueue<String>> map = new ConcurrentHashMap<>();

    public void addElementToQueue(String key, String value){
        if (map.containsKey(key)){
            map.get(key).add(value);
        }
        else{
            ConcurrentLinkedQueue<String> queue = new ConcurrentLinkedQueue<>();
            queue.add(value);
            map.put(key, queue);
        }           
    }    
}
Run Code Online (Sandbox Code Playgroud)

我担心的是,当多个线程尝试向 Map 添加新值时,第一个线程将使用新的 Queue 放置一个新的 Map 条目,第二个线程将等待,然后为该键放置一个新的 Queue,而不是添加到队列。我的并发/并发 API 知识充其量也很有限。也许并发是为了避免这种情况?非常感谢您的建议。

jta*_*orn 5

这种模式可能已经在 SO 上发布了很多次(有效地添加到并发映射):

Queue<String> q = map.get(key);
if(q == null) {
  q = new ConcurrentLinkedQueue<String>();
  Queue<String> curQ = map.putIfAbsent(key, q);
  if(curQ != null) {
    q = curQ;
  }
}
q.add(value);
Run Code Online (Sandbox Code Playgroud)

请注意,从 Java 8 开始,这可以替换为computeIfAbsent().