synchronizedCollection和contains - 我需要手动同步吗?

Div*_*ood 3 java synchronization

我在Java中使用Collections.synchronizedCollection来保护我知道很多线程同时访问的Set.Java API警告:

"当迭代它时,用户必须手动同步返回的集合:

Collection c = Collections.synchronizedCollection(myCollection);
     ...
  synchronized(c) {
      Iterator i = c.iterator(); // Must be in the synchronized block
      while (i.hasNext())
         foo(i.next());
  }
Run Code Online (Sandbox Code Playgroud)

"

如果我使用c.contains(obj),那是否是线程安全的?在内部,显然,这是迭代Collection并查看其中的任何对象是否等于obj.我的直觉是假设这可能是同步的(如果不是这似乎是一个重大的失败),但考虑到先前的同步痛苦,仔细检查似乎是明智的,谷歌搜索这方面的答案还没有转变任何东西.

eri*_*son 7

本身,呼叫contains是安全的.

问题是人们经常测试集合是否包含元素,然后根据结果​​对集合执行某些操作.

最有可能的是,测试和操作应该被视为单个原子操作.在这种情况下,应该获得对集合的锁定,并且应该在synchronized块中执行这两个操作.

  • 在那种情况下,为什么不添加它呢?基础集实现在做什么?例如,对于一个HashSet,一个包含然后一个add正在做加倍的工作.在您的情况下,无论Set实现添加将是关于同步的原子操作,并且您的add()代码无论如何都需要处理重复(即使它本身只是检查contains())以便正确地满足合同加(). (2认同)