java - 迭代 LinkedHashSet 时跳过同步并且未完成删除?

标签 java multithreading synchronization set synchronized

我必须迭代在多个线程之间共享的 Set。像这样的代码:

class MyObj{}
final static Set<MyObj> instances = Collections.synchronizedSet(new LinkedHashSet<MyObj>());
// returns the same object from the set if any, or add it if not found
public MyObj test2(MyObj a){

    if(instances.add(a))
            return a;

    for(MyObj o : instances){
        if(o.equals(a))
             return o;
    }

    throw new IllegalStateException("Impossible to reach this line");
}

我已经阅读了synchronizedSet的javadoc,它指出:

It is imperative that the user manually synchronize on the returned set when iterating over it:

Set s = Collections.synchronizedSet(new HashSet());
  ...   synchronized (s) {
  Iterator i = s.iterator(); // Must be in the synchronized block
  while (i.hasNext())
      foo(i.next());  
  }   

Failure to follow this advice may result in non-deterministic behavior.

但是,我还阅读了 this answer LinkedHashSet 提供插入顺序迭代。线程对我的集合所做的所有事情就是

  • 尝试添加一个新对象
  • 如果添加操作返回false,请对其进行迭代以测试对象
  • 永远不要执行清除或删除操作,集合只会增长。
有了所有这些假设,我的猜测是我不需要在集合上执行同步,因为即使另一个线程在我迭代它时添加了一个新对象,它也将位于集合的末尾,并且我会在到达插入点之前找到我正在寻找的对象。

这是正确的吗?

最佳答案

不,您必须同步,如 Javadoc 中所述。 :

Note that this implementation is not synchronized. If multiple threads access a linked hash set concurrently, and at least one of the threads modifies the set, it must be synchronized externally.

如果您有一个线程在另一个线程向其中添加元素时迭代该集合,您将收到 ConcurrentModificationException

The iterators returned by this class's iterator method are fail-fast: if the set is modified at any time after the iterator is created, in any way except through the iterator's own remove method, the iterator will throw a ConcurrentModificationException.

关于java - 迭代 LinkedHashSet 时跳过同步并且未完成删除?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39334217/

相关文章:

java - 在Linux中运行jnotify程序时引发异常

c++ - 使用 const bool 引用进行后台任务取消跟踪? (C++)

java - 调用FutureTask的run方法时如何消除sonar qube问题?

java - 如何使用 Java 检测同步冲突

java - 在我的示例中,同步和锁定之间有什么区别?

java - "Cannot instantiate the Type Main"

java - 如何在 Apache Poi XWPFDocument 的单个 XWPFRun 中对字符/单词应用不同的颜色?

Java-向 Hashmap 添加唯一值

java - CopyOnWriteArrayList 抛出 CurrentModificationException

python - 在Python2.7中实现Barrier