设计线程安全的类
1.实例封闭:意思是将数据封装在对象内部,它将数据的访问限制在对象的方法上,从而更容易确保线程在访问数据时总能持有正确的锁。当一个非线程安全对象被封装到另一对象中时,能够访问被封装对象的所有代码路径都是已知的。这和在整个程序中直接访问非线程对象相比,更易于对代码进行分析。
PointList 的状态由 ArrayList 来管理,但是 ArrayList 并非线程安全的。由于 ArrayList 私有并且不会逸出,因此 ArrayList 被封闭在 PointList 中。唯一能够访问 ArrayList 的路径都上同步锁了,也就是说 ArrayList 的状态完全有 PointList 内置锁保护,因而 PointList 是一个线程安全的类
public class PointList{ //非线程安全对象 myList private final ArrayList<SafePoint> myList = new ArrayList<SafePoint>(); //所有访问 myList 的方法都是用同步锁,确保线程安全 public synchronized void addPoint(SafePoint p) { myList.add(p); } //所有访问 myList 的方法都是用同步锁,确保线程安全 public synchronized boolean containsPoint(SafePoint p) { return myList.contains(p); } //所有访问 myList 的方法都是用同步锁,确保线程安全 //发布SafePoint public synchronized SafePoint getPoint(int i) { return myList.get(i); } //ThreadSafe(可发布的可变线程安全对象) class SafePoint{ private int x; private int y; private SafePoint(int[] a) {this(a[0], a[1]);} public SafePoint(SafePoint p) {this(p.get());} public SafePoint(int x, int y) { this.x = x; this.y = y; } //使用同步锁,确保线程安全 public synchronized int[] get() { return new int[] {x, y}; } //使用同步锁,确保线程安全 public synchronized void set(int x, int y) { this.x = x; this.y = y; } } }
线程安全性委托:
如果各个状态变量是相互独立的并且互不依赖,并且没有复合操作,那么可以将线程安全性委托给底层的状态变量。如将安全性委托给 value
public class SafeSequene{ private value = new AtomicInteger(0); //返回一个唯一的数值 public synchronized int getNext(){ return value.incrementAndGet(); } }
继承现有的线程安全的类,去重写它的线程安全的方法
客户端加锁:
public class ListHelper<E> { public List<E> list = Collections.synchronizedList(new ArrayList<>()); 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; } @Override public synchronized boolean add(T arg0) { list.add(arg0); return false; } @Override public synchronized void clear() { // TODO Auto-generated method stub list.clear(); } //按照此同步方式实现其他方法 }
参考:
本文来自博客园,作者:LeeJuly,转载请注明原文链接:https://www.cnblogs.com/peterleee/p/11396890.html

浙公网安备 33010602011771号