设计线程安全的类 VS 发布线程安全的对象

 

一、设计线程安全的类

步骤:

找出构成对象状态的所有变量

找出约束状态变量的不变性条件

建立对象状态的并发访问策略

 

1.在现有的线程安全类中添加功能

(1)重用能减低工作量和提高正确性

(2)如果底层的类改变了同步策略,使用不同的锁来保护它的状态,则子类会被破坏

class BetterVector<E> extends Vector<E>{
    public  synchronized boolean putIfAbsent(E e){
        boolean absent = !contains(e);
        if(absent){
            add(e);
        }
        return absent;
    }
}

 

2.客户端加锁机制

(1)对于使用对象X的客户端,如果知道X使用的是什么锁,则使用X本身用于保护其状态的锁,来保护这段客户端代码

(2)同样会破坏同步策略的封装

  A.错误示例:

class ListHelper<E>{
    public List<E> list = Collections.synchronizedList(new ArrayList<E>());
    
    public synchronized boolean putIfAbsent(E e){
        boolean absent = !list.contains(e);
        if(absent){
            list.add(e);
        }
        return absent;
    }
}

 B.正确示例:

class ListHelper<E>{
    public List<E> list = Collections.synchronizedList(new ArrayList<E>());
    
    public  boolean putIfAbsent(E e){
        synchronized(list){
            boolean absent = !list.contains(e);
            if(absent){
                list.add(e);
            }
            return absent;
        }
    }
}

 

3.组合:推荐方式

class ImprovedList<E> implements List<E>{
private final List<E> list;
public ImprovedList(List<E> list){ this.list = list; } public synchronized boolean putIfAbsent(E e){ boolean absent = !list.contains(e); if(absent){ list.add(e); } return absent; } public synchronized boolean add(E e) { //委托..... } }

 

 

二、发布线程安全的对象

1. 发布对象:使对象能在当前作用域之外的代码中使用。既将对象的引用传递到其他类的变量和方法。

(1)变量的静态初始化

(2)声明为volatile变量 或 AtomicReferance对象

(3)声明为final变量

(4)将变量保存在线程安全的容器中(既保存在一个由锁保护的域中)

 

2. 成员变量的初始化:

(1)直接初始化

(2)构造函数初始化

 

3. 不可变对象、可变对象

在Java内存模型中,final域能确保初始化过程的安全性,从而可以不受限制的访问不可变对象,并在共享这些对象时无需同步。

在可变对象基础上构建的不可变类:虽然Set对象是可变的,但Set对象通过ThreeStooges的构造函数后,无法对其修改。

 

public final class ThreeStooges {
    private final Set<String> stooges = new HashSet<String>();
    
    public ThreeStooges(){
        stooges.add("A");
        stooges.add("B");
        stooges.add("C");
    }
    
    public boolean isStooge(String name){
        return stooges.contains(name);
    }
}

 

posted @ 2014-09-20 18:20  等风来。。  Views(295)  Comments(0Edit  收藏  举报
------------------------------------------------------------------------------------------------------------ --------------- 欢迎联系 x.guan.ling@gmail.com--------------- ------------------------------------------------------------------------------------------------------------