首页 > 代码库 > 《Java并发编程实战》第四章 对象的组合 读书笔记

《Java并发编程实战》第四章 对象的组合 读书笔记


一、设计线程安全的类

在设计线程安全类的过程中,需要包含以下三个基本要素: 
. 找出构成对象状态的所有变量。 
. 找出约束状态变量的不变性条件。 
. 建立对象状态的并发访问管理策略。

分析对象的状态,首先从对象的域开始。 变量按作用域划分:
. 全局变量
. 局部变量
. 方法行参
. 异常处理参数


1. 收集同步需求
如果不了解对象的不变性条件与后验条件,那么就不能确保线程安全性。要满足在状态变量的有效值或状态转换上的各种约束条件,就需要借助原子性和封装性。
说的更简略些是Java线程安全都是因为共享变量,共享变量后会因为多个线程同时修改导致不正确的问题,所以收集一共有多少处会涉及到这些需要同步的变量,只有收集说有可能出问题的因素基于此之上保证所有元素线程安全也才能保证程序是线程安全的。

2. 依赖状态的操作
先验条件是值满足某个条件之后才能进行处理。例如:首先判断一个队列是否为空,如果为空。。。,如果不为空。。。其中判断队列是否为空就是先验条件。
如果在某个操作中包含有基于状态的先验条件,那么这个操作就称为依赖状态的操作。
? 满足可见性就可以?

3. 状态的所有权
单独一个基本对象比较保证其安全性,但是如果是包含对象的集合(容器类 例如:ArrayList),容器类通常表现出一种“所有权分离”的形式。
即使用线程安全的容器类(Collections.synchronizedList(List<T>)),也只能保证容器相关的操作是线程安全的,如果发布了可变对象的引用,就不会拥有独占的控制权。(非线程安全)


二、实例封装

将数据封装在对象内部,可以将数据的访问限制在对象的方法上,从而更容易确保线程在访问数据时总能持有正确的锁。
封闭机制更易于构造线程安全的类,因为当封闭类的状态时,在分析类的线程安全性时就无须检查整个程序。
即使封闭能保证对象内所有处理都是现成安全的,但是还需要注意当对象发布后还是可能出现问题,例如HashSet<Persion> 除保证Persion是线程安全外,还需要保证使用它的Set集合是线程安全的。
     - 例子 对象中仅有一个变量,保证此变量线程安全。在方法上使用synchronized

1. Java监听器模式
synchronized通过指定对象锁定

2. 示例:车辆追踪
     - 保证容器类实例、容器类包含元素实例线程安全。


三、线程安全性的委托

. 实例讲诉如何保证集合类及其包含类线程安全性

. 在现有的线程安全类中添加功能
继承自当前集合类,加锁使添加的方法保证安全性,但是这样比较脆弱。
组合方式,查看书籍源码

. 将同步策略文档化