gpt4 book ai didi

java - HashMap 与 ConcurrentHashMap : transfer between threads

转载 作者:行者123 更新时间:2023-12-03 13:18:32 25 4
gpt4 key购买 nike

我有一个关于在多线程应用程序中使用 map 的问题。假设我们有这样的场景:

  • 线程接收 json 数据为 List<Map<String, Object>>由 Jackson Json 反序列化。
  • 该线程修改接收到的 map 。
  • 然后将列表放入阻塞队列以供另一个线程使用。

  • 如您所见, map 仅由单个线程修改,但随后它“变为”只读(没有变化,只是不再修改)并传递给另一个线程。接下来,当我研究 HasMap 的实现时(还有 TreeMap )和 ConcurrentHashMap , 后者有 volatile字段,而前两个不是。那么, Map 的哪个实现我应该在这种情况下使用吗?是否 ConcurrentHashMap是矫枉过正的选择还是由于线程间传输而必须使用?
    我的简单测试表明我可以使用 HashMap/TreeMap当它们被同步修改并且有效时,但我的结论或我的测试代码可能是错误的:
    def map = new TreeMap() // or HashMap
    def start = new CountDownLatch(1)
    def threads = (1..5)
    println("Threads: " + threads)
    def created = new CountDownLatch(threads.size())
    def completed = new CountDownLatch(threads.size())
    threads.each {i ->
    new Thread({
    def from = i * 10
    def to = from + 10
    def local = (from..to)
    println(Thread.currentThread().name + " " + local)
    created.countDown()
    start.await()
    println('Mutating by ' + local)
    local.each {number ->
    synchronized (map) {
    map.put(number, ThreadLocalRandom.current().nextInt())
    }
    println(Thread.currentThread().name + ' added ' + number + ': ' + map.keySet())
    }
    println 'Done: ' + Thread.currentThread().name
    completed.countDown()
    }).start()
    }

    created.await()
    start.countDown()
    completed.await()
    println('Completed:')
    map.each { e ->
    println('' + e.key + ': ' + e.value)
    }
    主线程产生 5 个同步更新公共(public) map 的子线程,当它们完成主线程成功地看到子线程的所有更新。

    最佳答案

    java.util.concurrent类(class)有special guarantees关于测序:

    Memory consistency effects: As with other concurrent collections, actions in a thread prior to placing an object into a BlockingQueue happen-before actions subsequent to the access or removal of that element from the BlockingQueue in another thread.


    这意味着您可以自由使用任何类型的可变对象并根据需要对其进行操作,然后将其放入队列中。检索到它时,您应用的所有操作都将可见。
    (更一般地请注意,您演示的那种测试只能证明缺乏安全性;在大多数实际情况下,非同步代码在 99% 的情况下都可以正常工作。最后 1% 会咬你。)

    关于java - HashMap 与 ConcurrentHashMap : transfer between threads,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63952419/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com