状态空间:对象与变量所有可能的取值,状态空间越小,就越容易判断线程的状态,final域用得越多,就越能简化对象可能状态的分析过程(不可变对象只有唯一的状态)。
实例封闭:将数据封装在对象内部,并且用锁来保护所有访问路径。
Java监视器模式:一种编写代码的约定,把对象的所有可变状态都封装起来,并由对象自己的内置锁来保护,优势在于其简单性(进一步优化可以考虑使用私有锁对象,使得客户代码无法得到锁)。
因为我们不希望每一次内存访问都进行线程安全性分析,成本太高,而是希望将一些现有的线程安全组件组合为更大规模的线程安全组件或程序。
(1)找出构成对象状态的所有变量(引用其他对象则包含引用对象的域);
(2)找出约束状态变量的不变性条件;
(3)建立对象状态的并发访问管理策略。
(1)定义了如何在不违背对象不变性条件或后验条件的情况下对其状态的访问操作进行协同;
(2)规定了如何将不可变性、线程封闭与加锁机制等结合起来以维护线程的安全性,规定了哪些变量由哪些锁来保护;
(3)要确保开发人员可以对这个类进行分析与维护,同步策略必须被写为正式文档。
(1)单个安全的状态变量,可直接委托;
(2)多个彼此独立的安全状态变量,在多个变量上不增加不变性条件,可直接委托;
(3)多个非独立状态变量,需要做到以下2点:
a. 通过加锁机制维护不变性条件;
b. 避免发布状态变量到外部,防止客户代码破坏不变性条件。
(4)把线程安全性委托给某个对象的底层状态变量时,发布这些变量的条件:
a. 变量本身是线程安全的;
b. 没有任何不变性条件来约束它的值;
c. 不存在任何不允许的状态转换。