Java 在对ConcurrentHashMap进行迭代时添加和删除ConcurrentHashMap中的值

Java 在对ConcurrentHashMap进行迭代时添加和删除ConcurrentHashMap中的值,java,collections,concurrency,java-8,java-stream,Java,Collections,Concurrency,Java 8,Java Stream,我有以下代码: private ConcurrentMap<String, Integer> myMap = new ConcurrentHashMap<>(); @Scheduled(fixedDelay = 600_000) public void foo(){ myMap.values().stream(). filter(predicate()). forEach(this::

我有以下代码:

private ConcurrentMap<String, Integer> myMap = new ConcurrentHashMap<>();

 @Scheduled(fixedDelay = 600_000)
 public void foo(){     
    myMap.values().stream().
                filter(predicate()).
                forEach(this::remove);
}

public void insert(String str, Integer value){
   myMap.put(str, value);
}
private ConcurrentMap myMap=new ConcurrentHashMap();
@计划(固定时间=600_000)
public void foo(){
myMap.values().stream()。
筛选器(谓词()。
forEach(这个::删除);
}
公共void插入(字符串str,整数值){
myMap.put(str,value);
}
如果在该映射上迭代时,有人将在其中添加新值或从中删除现有值,会发生什么情况?

的文档中有一些关于该行为的详细信息。首先,我们看一下什么是:

返回此映射中包含的值的
集合
视图

视图的迭代器和拆分器弱一致。

视图的
spliterator
报告
spliterator.CONCURRENT
spliterator.NONNULL

有趣的是术语和,其中前者被描述为:

大多数并发集合实现(包括大多数队列)也不同于通常的
java.util
约定,因为它们的迭代器和拆分器提供弱一致性而不是快速失败遍历:

  • 他们可以与其他行动同时进行
  • 他们永远不会抛出
    ConcurrentModificationException
  • 它们保证在施工时只穿过一次图元,并且可能(但不保证)反映施工后的任何修改
并被描述为:

特征值,表示可以由多个线程安全地同时修改元素源(允许添加、替换和/或删除),而无需外部同步。如果是这样的话,拆分器应该有一个关于遍历期间修改影响的文档化策略


根据所有这些文档,并且与
ConcurrentHashMap
的并发模型一致,这意味着流管道是完全线程安全的,并将在创建迭代器时遍历元素。

您尝试过什么吗?@BuhakeSindi-我不知道您在问什么我想说的是您是否创建了与您的场景匹配的测试用例。@BuhakeSindi-哦。。。我不知道如何编写这样的测试,不清楚this::remove应该做什么。这意味着类中必须有一个
remove
方法,它接收一个值来做什么?是否再次迭代映射以删除该值?考虑<代码> MyApp.Values().ReleVIF(谓词());<代码>相反…谢谢!在@BuhakeSindi的问题之后,我尝试编写一个单元测试,它使用几个线程来添加和删除这个映射中的元素(一些用于插入,一些用于删除)——在这段时间里,我运行了我的foo()方法,实际上——没有造成任何伤害。。。