客户端加锁,注意要使用同一个锁。
错误做法:
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;
}
}
因为这个锁是加上ListHelper上的,ListHelper辅助类,其他对list的操作使用了不同的锁,所以putIfAbsent对其他操作来说并不是原子的。
正确做法:
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;
}
}
}
更好的方法是使用
组合为现有的类添加原子操作:
class ImprovedList<E> implements List<E> {
private final List<E> list;
public ImprovedList(List<E> list) {
this.list = list;
}
public synchronized boolean putIfAbsent(E x) {
boolean absent = !list.contains(x);
if(absent) {
list.add(x);
}
return absent;
}
客户端不再直接使用这个对象,而结合能通过ImprovedList来说它。