【问题标题】:Java Multi threading consumer with ConcurrentHashmap strategy具有 ConcurrentHashmap 策略的 Java 多线程使用者
【发布时间】:2019-05-17 06:29:31
【问题描述】:

我们有一个使用 ConcurrentHashmap 队列的经典生产者/消费者方法的多线程应用程序。

消费者启动一个线程,该线程内部有一个无限循环,并发哈希映射上的另一个嵌套循环读取并删除每个已处理的项目。

我问自己这段代码对于地图上的“for”迭代和每个元素的“remove”是否安全/有效。

运行代码好像是对的……

new Thread(t.getContextName()+"-RespMsgThread") {
            public void run() {
                try {
                    do {

                        for (Entry<Integer, AbstractMessage> nodeEntry : t.getHtForResponse().entrySet()) 
                            {

                               --> Doing some stuff with the node Entry

                              // remove the node from the queue 
                              t.getHtForResponse().remove(nodeEntry.getKey());
                        }

                        yield();
                    }
                    while (!t.isStopControllerRun());

                } catch (InterruptedException ex) {
                    Context.getInstance().getLogger().info("ERROR: " + ExceptionUtils.getStackTrace(ex));
                }
            }
        }.start();

【问题讨论】:

  • 请提供更多细节,问题不清楚。顺便说一句,默认情况下 ConcurrentHashmap 对于迭代是安全的。
  • 你用的是什么java版本?
  • Java 8. for on 条目是否安全尊重将物品放入其中并删除的消费者?
  • 你考虑过使用java流吗?
  • 还没有。你认为我可以有一个更有效/更安全的算法吗?

标签: java multithreading concurrenthashmap


【解决方案1】:

是的,它完全安全/高效地尊重“for”迭代。有一个问题,因为 ConcurrentHashMap 的迭代器是弱一致的,您可以删除未处理的键的值(在您的情况下使用节点条目做一些事情)。

所以可以考虑调用方法

remove(Object key, Object value)
removes the entry for a key only if currently mapped to a given value.

而不是普通的 remove(Object key) 方法

【讨论】:

    【解决方案2】:

    当地图中没有你只让出的物品时,也许你可以睡觉。作为睡眠的替代方法,您可以使用BlockingQueue 之类的东西。通过在 BlockingQueue 上使用 take() 方法,您将在插入项目后立即获得项目。 您也可以使用poll(timeout, timeunit) 方法来检查线程是否已停止。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-12-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多