一、设计线程安全的类
在设计线程安全类的过程中,须要包括下面三个基本要素:
. 找出构成对象状态的全部变量。
. 找出约束状态变量的不变性条件。
. 建立对象状态的并发訪问管理策略。
分析对象的状态,首先从对象的域開始。 变量按作用域划分:
. 全局变量
. 局部变量
. 方法行參
. 异常处理參数
1. 收集同步需求
假设不了解对象的不变性条件与后验条件,那么就不能确保线程安全性。要满足在状态变量的有效值或状态转换上的各种约束条件。就须要借助原子性和封装性。
说的更简略些是Java线程安全都是由于共享变量,共享变量后会由于多个线程同一时候改动导致不对的问题,所以收集一共同拥有多少处会涉及到这些须要同步的变量,仅仅有收集说有可能出问题的因素基于此之上保证全部元素线程安全也才干保证程序是线程安全的。
2. 依赖状态的操作
先验条件是值满足某个条件之后才干进行处理。比如:首先推断一个队列是否为空,假设为空。
。。
,假设不为空。。
。当中推断队列是否为空就是先验条件。
假设在某个操作中包括有基于状态的先验条件。那么这个操作就称为依赖状态的操作。
? 满足可见性就能够?
3. 状态的全部权
单独一个基本对象比較保证其安全性,可是假设是包括对象的集合(容器类 比如:ArrayList),容器类通常表现出一种“全部权分离”的形式。
即使用线程安全的容器类(Collections.synchronizedList(List<T>)),也仅仅能保证容器相关的操作是线程安全的,假设公布了可变对象的引用。就不会拥有独占的控制权。(非线程安全)
二、实例封装
将数据封装在对象内部,能够将数据的訪问限制在对象的方法上,从而更easy确保线程在訪问数据时总能持有正确的锁。
封闭机制更易于构造线程安全的类,由于当封闭类的状态时,在分析类的线程安全性时就无须检查整个程序。
即使封闭能保证对象内全部处理都是现成安全的,可是还须要注意当对象公布后还是可能出现故障,比如HashSet<Persion> 除保证Persion是线程安全外,还须要保证使用它的Set集合是线程安全的。
- 样例 对象中仅有一个变量,保证此变量线程安全。在方法上使用synchronized
1. Java监听器模式
synchronized通过指定对象锁定
2. 演示样例:车辆追踪
- 保证容器类实例、容器类包括元素实例线程安全。
三、线程安全性的托付
. 实例讲诉怎样保证集合类及其包括类线程安全性
. 在现有的线程安全类中加入功能
继承自当前集合类,加锁使加入的方法保证安全性,可是这样比較脆弱。
组合方式,查看书籍源代码
. 将同步策略文档化