试图理解接受的答案 - 线程安全的队列图

时间:2015-02-01 08:47:13

标签: java multithreading design-patterns concurrency thread-safety

Thread safe Map of Queues

以上问题的设计实现非常类似于我自己。我明白为什么它不是线程安全的,但是接受的“模式”让我陷入了一个循环。我不太了解如何实现它或它与问题的关系。

    boolean send = false;
    System.out.println("MailCenter Size Start: " + mailBox.keySet().size());
    if (parsedInput.size() == 3) {
        for (String s : writers.keySet()) {
            if (!s.equals(parsedInput.get(1))) {
                send = true;
            }
        }
        if (send) {
            mailMessage.add(noAnsiName + ": " + parsedInput.get(2));
            mailBox.putIfAbsent(parsedInput.get(1), mailMessage);
            System.out.println("Current mail message is: " + mailMessage.peek());
            out.println("SERVER You have sent mail to " + parsedInput.get(1) + ".");
        }
        System.out.println("MailCenter Size Middle: " + mailBox.keySet().size());
    } else {
        int loop = 0;
        for (Map.Entry entry : mailBox.entrySet()) {
            System.out.println(entry.getKey() + ":\t" + entry.getValue());
            System.out.println("*** LOOP STATUS *** " + loop);
            loop++;
        }
    }

1 个答案:

答案 0 :(得分:1)

  

我不太了解如何实现它或它在关系中的作用   问题。

问题显示正在使用ConcurrentHashMap。但是,变量map被声明为Map,因此接受的答案引用的方法putIfAbsent()不可见。

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

因此,为了使答案奏效,必须更改上述内容以将map声明为ConcurrentMap

现在,这是迈向线程安全的一个很好的一步。但是,仅仅因为我们使用并发映射实现并不意味着地图上的get()和后续put()是原子工作单元。换句话说,在当前线程调用get()之后,但在调用put()之前,另一个线程仍然可以更改映射的状态。

答案建议putIfAbsent(),因为通过在同步块中包含等效的containsKey()调用和put()调用来确保原子性。如果您还正确使用了返回值,则将具有可靠的并发行为。

相关问题