Java 列表上同步的这两种用法在行为上有什么区别 List List=new ArrayList(); 列表。添加(“a”); ... 列表。添加(“z”); 已同步(列表){ 迭代器i=list.Iterator(); while(i.hasNext()){ ... } }
及Java 列表上同步的这两种用法在行为上有什么区别 List List=new ArrayList(); 列表。添加(“a”); ... 列表。添加(“z”); 已同步(列表){ 迭代器i=list.Iterator(); while(i.hasNext()){ ... } },java,concurrency,synchronized,Java,Concurrency,Synchronized,及 List List=new ArrayList(); 列表。添加(“a”); ... 列表。添加(“z”); List synchronizedList=集合。synchronizedList(列表); 已同步(synchronizedList){ 迭代器i=synchronizedList.Iterator(); while(i.hasNext()){ ... } } 具体地说,我不清楚为什么在第二个实例中,当同步列表提供对列表的线程安全访问时,需要使用synchronized。如果不锁
List List=new ArrayList();
列表。添加(“a”);
...
列表。添加(“z”);
List synchronizedList=集合。synchronizedList(列表);
已同步(synchronizedList){
迭代器i=synchronizedList.Iterator();
while(i.hasNext()){
...
}
}
具体地说,我不清楚为什么在第二个实例中,当同步列表提供对列表的线程安全访问时,需要使用
synchronized
。如果不锁定迭代,如果另一个线程在循环期间修改它,您将得到ConcurrentModificationException
同步所有的方法丝毫不能阻止这一点
这就是为什么Collections.synchronized*
完全无用的原因。您应该使用
java.util.concurrent
中的类。(你应该仔细考虑如何保证自己的安全)
作为一般经验法则:
在每个方法上都使用锁并不足以保证线程安全
有关更多信息,请参见
synchronizedList
仅使每个调用原子化。在您的情况下,循环进行多个调用,因此在每次调用/迭代之间,另一个线程可以修改列表。如果使用其中一个并发集合,则不会出现此问题
查看此集合与ArrayList的区别
List<String> list = new ArrayList<String>();
list.add("a");
...
list.add("z");
List<String> synchronizedList = Collections.synchronizedList(list);
synchronized(synchronizedList) {
Iterator<String> i = synchronizedList.iterator();
while(i.hasNext()) {
...
}
}
由于同步列表的实现方式,第二个代码需要同步。解释如下: 用户在遍历返回的列表时,必须手动同步该列表 两个代码段之间的主要区别在于
add
操作的效果:
- 对于同步列表,您有一个可见性保证:例如,如果其他线程调用
,它们将看到新添加的项synchronizedList.get(…)
- 使用ArrayList,其他线程可能不会立即看到新添加的项—实际上可能永远也看不到它们
synchronizedList()
,您将需要提供更高级别的同步(这意味着您将拥有足够的自己的锁,而不需要它),或者您将有竞争条件。@SLaksL:我的观点是这一点的反映-如果您不使用synchronizedList(),除了需要的其他锁定之外,您还需要实现synchronizedList()提供的锁定。但我同意,您确实需要考虑所需的锁定,而不是使用诸如synchronizedList之类的便利设施作为支撑。因此,当您使用java.util.concurrent
中的一个集合时,您根本不需要显式地在列表上设置锁定?只是想让我遵循正确的顺序…@Windle不,您不需要,迭代将在列表上完成,就像迭代开始时一样-迭代期间对列表所做的任何更改都将被忽略(在您的迭代中)。对于并发集合,如果使用锁,则无法访问任何锁。如果您想锁定它,您无法锁定它,但您不需要锁定它。;)@PeterLawreyArrays.asList(“a,b,c,d,e,f,g,h,z”。split(“,”)
这是我见过的最懒的事情!;-)@亚西莉亚:还有更多来自哪里的信息
List<String> list = new ArrayList<String>();
list.add("a");
...
list.add("z");
List<String> synchronizedList = Collections.synchronizedList(list);
synchronized(synchronizedList) {
Iterator<String> i = synchronizedList.iterator();
while(i.hasNext()) {
...
}
}
List<String> list = new CopyOnWriteArrayList<String>();
list.addAll(Arrays.asList("a,b,c,d,e,f,g,h,z".split(",")));
for(String s: list) {
System.out.print(s+" ");
// would trigger a ConcurrentModifcationException with ArrayList
list.clear();
}
a b c d e f g h z