//非线程安全
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);
}
return absent;
}
}
该方式不能保证线程安全,因为在错误的锁上进行了同步,无论List采用哪一种锁保护状态,可以确定的是,锁并不是List上的锁,List只是带来了同步的假象,尽管所有的链表操作都生命的原子的,却使用了不同的锁,意味着putIfAbsent相对于其他操作并不是原子的,因此无法确保putIfAbsent执行时,另一个线程不会修改链表。
//客户端枷锁实现线程安全
public class ListHelper<E>{
public List<E> list = Collections.synchronizedList(new ArrayList<E>());
...
public boolean putIfAbsent(E x){
synchronized(list){
boolean absent = !list.contains(x);
if(absent){
list.add(x);
}
return absent;
}
}
}
//组合实现没有则添加
public class ImprovedList<T> implements List<T>{
private final List<T> list;
public ImprovedList(List<T> list){
this.list = list;
}
public synchronized boolean putIfAbsent(T x){
boolean contains = list.contains(x);
if(contains){
list.add(x);
}
return !contains;
}
public synchronized void clear(){
list.clear();
}
}