java - ConcurrentHashMap 上的元素循环

标签 java concurrenthashmap thread-synchronization

我正在尝试实现一个对 ConcurrentHashMap 的元素进行循环的函数。例如,如果ConcurrentHashMap中有{a, b, c}元素,第一次调用该函数,它返回a,第二次,它返回b,第三次,它返回c,第四次,它返回a。

private static Enumeration<Peer> nhEnmu;
private static final ConcurrentHashMap<String, Peer> peers;

private synchronized static Peer getNextPeer()
{
    if (nhEnmu == null || !nhEnmu.hasMoreElements())
    {
        nhEnmu = peers.elements();
    }

    return nhEnmu.nextElement();
}

我按照上面的方法实现了这个函数,但是一直弹出NoSuchElementException,我想知道使用elements()方法有什么问题吗?如果不合适,我应该采用什么实现方式?谢谢!

异常跟踪如下:

at Main$MsgProcessorThread.run(Main.java:119)
Exception in thread "Thread-1" java.util.NoSuchElementException at
java.util.concurrent.ConcurrentHashMap$HashIterator.nextEntry(ConcurrentHashMap.java:1266) at
java.util.concurrent.ConcurrentHashMap$ValueIterator.nextElement(ConcurrentHashMap.java:1297) at 
control.Protocol.getNextPeer(Protocol.java:89)

最佳答案

根据this question返回的迭代器不是线程安全的。如果是这样,并且您在多个线程上访问迭代器,则可能会发生此异常。

您可能也有在此类中添加和删除对等点的方法。尝试保留一个对等点列表以及该列表的索引。当您删除某个对等点时,请从 HashMap 和对等点循环列表中删除该对等点,并相应地更新您的索引。添加时执行相同的操作。

然后,当调用 getNextPeer 时,返回列表中的下一个对等点并增加索引。如果索引超出列表的大小,则回滚到零。

有点像......

private static List<Peer> nhEnmu;
private static int index;
private static final ConcurrentHashMap<String, Peer> peers;

private synchronized static Peer getNextPeer()
{
    Peer peer = null;
    if (nhEnmu.size()>0)
    {
        peer = nhEnmu.get(index);
        index++;
        if(index>=nhEnmu.size())
            index = 0;
    }
    return peer;
}

关于java - ConcurrentHashMap 上的元素循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17769818/

相关文章:

java - 在 Slick2d 像素游戏中相机跟随玩家的方法

java - 在插入 BST 期间获取实际索引

Javafx 10 或更早版本可供下载以创建可运行的 jar 文件

java - 更改Hadoop HDFS文件名

java - HashMap 的线程安全实现

java - 如何处理需要组合起来创建响应的多个客户端请求?

android - 从 OpenGL 线程使用时 Handler.dispatchMessage 挂起/崩溃

java - 在这个例子中使用ConcurrentMap.replace有什么意义

java - 什么东西便宜 : Traversal using n iterators of a single ConcurrentHashMap or n instances of a HashMap

c - 读者-作家问题作家偏好(读者可能会挨饿)