Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java ConcurrentHashMap上的元素循环_Java_Concurrenthashmap_Thread Synchronization - Fatal编程技术网

Java ConcurrentHashMap上的元素循环

Java ConcurrentHashMap上的元素循环,java,concurrenthashmap,thread-synchronization,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

我正在尝试实现一个函数,该函数对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();
}
根据所述,返回的迭代器不是线程安全的。如果是这样,并且您正在多线程上访问迭代器,则可能会发生此异常

您可能也有一个方法来添加和删除此类中的对等点。试着保留一个同龄人列表和该列表的索引。删除对等方时,请从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;
}
私有静态列表nhEnmu;
私有静态int索引;
私有静态最终ConcurrentHashMap对等点;
私有同步静态对等getNextPeer()
{
对等=空;
如果(nhEnmu.size()>0)
{
peer=nhEnmu.get(索引);
索引++;
如果(索引>=nhEnmu.size())
指数=0;
}
返回同伴;
}
根据分析,返回的迭代器不是线程安全的。如果是这样,并且您正在多线程上访问迭代器,则可能会发生此异常

您可能也有一个方法来添加和删除此类中的对等点。试着保留一个同龄人列表和该列表的索引。删除对等方时,请从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;
}
私有静态列表nhEnmu;
私有静态int索引;
私有静态最终ConcurrentHashMap对等点;
私有同步静态对等getNextPeer()
{
对等=空;
如果(nhEnmu.size()>0)
{
peer=nhEnmu.get(索引);
索引++;
如果(索引>=nhEnmu.size())
指数=0;
}
返回同伴;
}


直接使用ConcurrentHashMap.entrySet()。它是安全的。

直接使用ConcurrentHashMap.entrySet()。它是安全的。

我们可以看到异常报告吗?当然@tbodt,我在post中包含了该报告。刚刚意识到,如果hashmap为空,则会发生此异常。获得枚举并不意味着它有项。注意:不要使用枚举。它们已经过时了,使用它们是一个坏习惯。您需要
对等点.values().iterator()
。我们可以查看异常报告吗?当然@tbodt,我在post中包含了该报告。如果hashmap为空,则会发生此异常。获得枚举并不意味着它有项。注意:不要使用枚举。它们已经过时了,使用它们是一个坏习惯。你需要
peers.values().iterator()
。我的答案中链接的问题与此相矛盾。我不这么认为,它说:“总之,像for(Object o:someConcurrentHashMap.entrySet()){//…}这样的语句几乎每次你看到它时都是好的(或者至少是安全的)。”如果你总是链接到entrySet(),它是安全的,但它可能会在迭代过程中发生变化,并引发异常。这几乎是这里的关键词。如果有多个线程在结构上运行,这是不安全的。我的错误!entrySet()从不抛出异常,但当您遍历它时,其他线程会等待您完成,然后他们可以编写我的答案中链接的问题与此相矛盾。我不这么认为,它说:“总之,像for(Object o:someConcurrentHashMap.entrySet()){/…}这样的语句就可以了(或者至少是安全的)如果你总是链接到entrySet(),它是安全的,但是在迭代过程中它可能会改变,并且可能引发异常。几乎是这里的关键词。如果有多个线程在结构上运行,这是不安全的。我的错误!entrySet()从不引发异常,但当您遍历该异常时,其他线程会等待您完成,然后它们可以写入。我尝试在函数和nhEnmu迭代器上使用synchronized关键字,但是,该异常仍然存在。我想知道应该怎么做才能使这个函数线程安全?我会放弃枚举,而采用我在编辑中建议的方法。或者,查找
ConcurrentHashMap
的源代码,查看枚举的具体操作。我只是查看了源代码,它很复杂。我尝试在函数和nhEnmu迭代器上使用synchronized关键字,但是,这个异常仍然存在。我想知道应该怎么做才能使这个函数线程安全?我会放弃枚举,而采用我在编辑中建议的方法。或者,查找
ConcurrentHashMap
的源代码,查看枚举的具体操作。我只是看了看来源,它很复杂。