设计线程安全的类

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();
    }
    
    //按照此同步方式实现其他方法
    
}

 

参考:
posted @ 2019-08-22 21:12  LeeJuly  阅读(240)  评论(0)    收藏  举报