我正在尝试实现一个对 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/