【发布时间】:2017-10-06 14:12:58
【问题描述】:
From Javadocs for Collections class:
public static <T> List<T> synchronizedList(List<T> list)
返回由指定支持的同步(线程安全)列表 列表。 为了保证串行访问,所有 对“后备名单”的访问是通过返回的 列表。
我是否理解正确,“支持列表”是指方法参数(列表),所以在代码行下面List<String> mySyncList = Collections.synchronizedList(origList); 我永远不会做类似 origList.anyMethodCall() 的事情,包括:origList.add("blabla") 或 @987654330 @, origList.set(1, "blabla")?虽然它编译!我可以通过不进行结构修改(origList.contains("blabla"))的方式访问“支持列表”吗?我想,我可以,但它也是“获得后盾”!并且应该遵循 Oracle 官方文档...
对吗,只有在我从 mySyncList 获得迭代器之后,在我完成使用这个迭代器之前,origList 结构修改时才会出现这个问题?
如果是这样,我说得对吗,如果线程 3 在结构上修改了 origList,那么在任何其他线程中迭代 mySyncList 都会产生 ConcurrentModificationException,但只要线程 3 以非结构方式修改 origList,绝对没有问题(contains()),或者thread-3在结构上修改了origList但mySyncList中没有迭代(mySyncList.add,mySyncList.remove,...)?
public static void main(String[] args) {
List<String> origList = new ArrayList<>();
origList.add("one");
origList.add("two");
origList.add("three");
List<String> mySyncList = Collections.synchronizedList(origList);
origList.add("blabla"); // prohibited by Oracle ??? :)))
origList.add("blabla"); // prohibited by Oracle ??? :)))
origList.add("blabla"); // prohibited by Oracle ??? :)))
origList.add("blabla"); // prohibited by Oracle ??? :)))
// now use mySyncList
System.out.println(mySyncList); // no problem so far
// P.S.: Maybe problem arises ONLY when origList STRUCTURALLY MODIFIED
// AFTER I obtained iterator from mySyncList and BEFORE I finished
// using this iterator? If so, such wording would be much preferable in
// official docs!
}
附:我的问题不同,我明白:
用户必须手动同步返回的 迭代时列出:
List list = Collections.synchronizedList(new ArrayList());
...
synchronized (list) {
Iterator i = list.iterator(); // Must be in synchronized block
while (i.hasNext())
foo(i.next());
}
所以研究没有产生答案,我认真审查了以下所有内容:
Why do I need to synchronize a list returned by Collections.synchronizedList
Collections.synchronizedlist() remove element while iterating from end
What is the use of Collections.synchronizedList() method? It doesn't seem to synchronize the list
- What cause java.util.concurrentmodificationexception using Collections.synchronizedList?
感谢格雷接受下面的答案,我终于得出以下结论(我对格雷的回答的简要概述):
写完“List mySyncList = Collections.synchronizedList(origList)”后建议写在下一行“origList = null”。在实践中,大师从不在代码中的任何地方使用 origList (在任何线程中,在整个 prog 中)。
理论上以后使用 origList 是没有问题的,只要不进行结构修改(添加,删除不调用),但实际上没有人可以安全地保证仅非结构访问。 p>
这背后的思想是:您将 origList 转换为线程安全的 mySyncList,现在只将 mySyncList 用于多线程目的而忘记 origList !!!
【问题讨论】:
-
确实抓住了这一点。你在问什么?
-
我可以在不进行结构修改的情况下访问“支持列表”吗?只有在安全发布的情况下。
标签: java multithreading list collections synchronized