java初始化线程安全问题

期望:

Map每个key都维护一个单例的LinkedBlockingQueue

问题点:

在初始化时时如何才能保证线程安全,双重加锁由于可见性原因不能起作用,求大神指教,能不能在map.get(key)为空时,得到一个线程安全的对象,避免多次初始化造成数据的不一致性的问题

事例代码如下:
Map<String, LinkedBlockingQueue<Map>> DATA_QUEUE = new ConcurrentHashMap<>();
    
    Object synlock = new Object();

    @Test
    public void test1(){

      new Thread(()-> produceData("1","2")).start();
      new Thread(()-> produceData("1","3")).start();
      new Thread(()-> produceData("1","4")).start();
      new Thread(()-> produceData("1","5")).start();
      new Thread(()-> produceData("1","6")).start();
      new Thread(()-> produceData("1","7")).start();
      System.out.println(DATA_QUEUE);


    }

    public void produceData(String key, Object data) {
        LinkedBlockingQueue queue = DATA_QUEUE.get(key);
        if (queue == null) {
                synchronized (synlock){
                    if(queue == null){
                        queue = new LinkedBlockingQueue();
                        System.out.println("init======"+queue.hashCode());
                    }
                }
        }
        try {
            queue.offer(data, 500, TimeUnit.MILLISECONDS);
            DATA_QUEUE.put(key, queue);
        } catch (InterruptedException e) {
            System.out.println("error");
        }
    }
阅读 1.9k
1 个回答
if (queue == null) {
    synchronized (synlock){
        if(queue == null){
            queue = new LinkedBlockingQueue();
            DATA_QUEUE.put(key, queue);
            System.out.println("init======"+queue.hashCode());
        } else {
            queue = DATA_QUEUE.get(key);
        }
    }
}

我觉着应该是这样,你把DATA_QUEUE.put(key, queue);放在外面的话,加锁就没意义了。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题