JAVA并发编程(三)设计线程安全的类

设计线程安全的类

设计线程安全类的过程中需要注意三个基本要素:

1、找出构成对象的所有变量

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

3、建立对象状态的并发访问管理策略

同步策略定义了如何在不违背对象不变性条件或者后验条件的情况下对其状态的访问操作进行协同。同步策略规定了如何将不变性、线程封闭和加锁机制等结合起来以维护线程的安全性,并且规定了哪些变量由哪些锁来保护。确保可以对这个类进行分析维护,就需要将同步策略写为正式文档。

如果不了解对象的不变性体条件,就不能确保线程安全性。要满足在状态变量的有效值或者状态转换上的各种约束条件,就需要借助于原子性和封装性。

实例封闭

封装简化了线程安全类的实现过程,将数据封装在对象内部,可以将数据的访问限制在对象的方法上,从而更容易确保线程在访问数据时总能持有正确的锁。

封装更易于构造线程安全的类,因为当封装类的状态时,在分析类的线程安全性时就无须检查整个程序。

线程安全性的委托

如果一个类由多个独立且线程安全的状态变量组成,并且在所有的操作中都不包含无效的状态转换,那么可以将线程安全性委托给底层的状态变量。
如果一个状态变量是线程安全的,并且没有任何不变性条件来约束它的值,在变量的操作上也不存在任何不允许的状态转换,那么久可以安全的发布这个变量。

同步容器类

在早期JDK中,同步容器只有Vector和HashTable,后来引入了Colletions.SynchronizedXX来创建同步容器,这些类实现线程安全的方式是:将它们的状态封装起来,并对每个公有方法都进行同步,使得每次只有一个线程能访问容器的状态。

尽管同步容器类是线程安全的,但是在某些情况下仍然需要额外的客户端加锁来保护复合操作。

并发容器

Java5.0提供了多种并发容器来改进同步容器的性能。同步容器将所有对容器状态访问都串行化,以实现它们的线程安全,这种方法的代价是严重降低了并发性。当多个线程竞争容器锁时,吞吐量将严重降低。

通过并发容器代替同步容器,可以极大的提高伸缩性,降低风险。

常用的类有ConcurrentHashMap,CopyOnWriteArrayList,BlockingQueue,

ConcurrentLinkedQueue,ConcurrentSkipListMap等等。

同步工具类

闭锁是一种同步工具类,可以延迟线程的进度直到到达终止状态。CountDownLactch是一种灵活的闭锁实现。

FutureTask也可以用做闭锁。

计数信号量Semaphore用来控制同时访问某个特定资源的操作数量,或者同时执行某个操作的数量。

栅栏能阻塞一组线程直到某个事件发生。栅栏与闭锁的关键区别在于,所有线程必须同时到达栅栏位置才能继续执行。闭锁用于等待事件,而栅栏用于等待其他线程。CyclicBarier是一种栅栏实现。






欢迎扫描二维码,关注公众号

JAVA并发编程(三)设计线程安全的类_第1张图片


你可能感兴趣的:(java,java编程)