对于以下代码,
public class ListHelper<E>{
public List<E> list =
Collections.synchronizedList(new ArrayList<E>());
.....
public synchronized boolean putIfAbsent(E x){
boolean absent = !list.contains(x);
if(absent){
list.add(x);
}
}
}
对于可以由多个线程访问的每个可变状态变量,必须使用相同的锁执行对该变量的所有访问。
执行putIfAbsent
操作时,是否(上图)是线程安全失败的原因?
答案 0 :(得分:1)
这是错误的锁定(ListHelper
上的同步而不是list
上的同步),此外,因为list
是公开发布的 - 任何人都可以访问{{1}对象。
将其设为私有,并确保没有人可以直接访问它(除此之外通过您提供的同步方法)并确保您在执行阅读时同步 - 而且您应该是金色的。
另一种方法是向读者提供列表的不可修改的副本。