0
点赞
收藏
分享

微信扫一扫

客户端加锁,注意要使用同一个锁


客户端加锁,注意要使用同一个锁。



错误做法:



class ListHelper<E> {
 
 
 

  public List<E> list = Collections.synchronizedList(new ArrayList<E>());
 
 
  
 
 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来说它。



举报

相关推荐

0 条评论