具有ConcurrentHashmap策略的Java多线程使用者

时间:2019-05-17 06:29:31

标签: java multithreading concurrenthashmap

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

使用者启动一个线程,该线程内部具有无限循环,并发散列图上的另一个嵌套循环可读取并删除每个已处理的项目。

我要问自己该代码相对于地图上的“ for”迭代和每个元素“删除”是否安全/高效。

运行代码似乎是正确的...

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();

2 个答案:

答案 0 :(得分:3)

是的,它对于“ for”迭代完全安全/有效。有一个陷阱,因为ConcurrentHashMap的迭代器是弱一致性的,因此您可以删除未处理的键的值(在这种情况下,使用节点Entry做一些事情)。

因此您可以考虑调用方法

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

代替普通的删除(对象键)方法

答案 1 :(得分:1)

如果地图上没有物品,您只能屈服,也许您可​​以睡觉。除了睡眠以外,您可以使用类似BlockingQueue的方法。通过在BlockingQueue上使用take()方法,您将在插入项目后立即获得它。 您还可以使用poll(timeout, timeunit)方法检查线程是否已停止。