【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>>
一、设计线程安全的类
在设计线程安全类的过程中,需要包含以下三个基本要素:
- 找出构建对象状态的所有变量
- 找出约束状态变量的不变性条件
- 建立对象状态的并发访问管理策略
在设计线程安全的类时,需要对对象状态的有效性进行判断,而对象状态的不可变条件主要有三种:先验条件、不变性条件和后验条件。要满足状态变量的有效值或状态转换上的各种约束条件,就需要借助于原子性和封装性。
二、实例封闭
实例封闭机制指的是将一个状态可变的对象的访问完全由另一个对象封装起来,这样就保证了该对象的所有访问路径都是线程安全的。从实例封闭机制里可以看出,被封装的对象是不允许单独的访问该对象的状态的,而必须使用封闭对象提供的路径。
三、线程安全性的委托
- 在一个状态可变对象内部拥有多个可变的状态,而这几个状态之间是相互独立的,即相互之间没有不变性条件约束,对于这样的对象就可以不对其进行额外的同步操作,而只需要对其内部各个状态的操作进行同步即可;
- 如果在类的状态变量之间存在某些不变性条件,那么这个类就必须提供自己的加锁机制以确保对这些变量的读取和更行操作都是同步操作。
四、在现有的线程安全类中添加新功能
在现有类中添加新的原子化功能有两种方式:继承和组合。
使用继承来添加新的原子化功能时需要保证两点:①新增加的功能需要维持父类的规范,理解其中的同步策略,这样才能与父类保持一致;②新的原子操作必须持有父类其他原子操作一样的锁。继承的缺点在于父类的原子操作的锁一般为其对象的内置锁,但如果父类改变了其策略,那么子类就很难保持与父类一致,并且由于扩展会使要添加的原子操作分布在各个类中,这增加了后期维护的难度。
组合相对于继承则比较灵活,因为通过组合而来的对象可以拥有自己的锁,其只需要维护其自定义的原子操作的安全性即可,并且由于被组合的对象的公共API一般是不会变化的,而组合的对象也只会使用这些公共API,因而这也保证了被组合对象改变其内部实现时而不会影响组合对象。
五、将同步策略文档化
在设计一个类时,应该在文档中说明客户代码需要了解的线程安全性保证,以及代码维护人员需要了解的同步策略。最起码,应该保证将类中的线程安全性文档化。如果你不想保证线程安全性也可以,但一定要明确的指出来;如果你希望客户代码能够在类中添加新的原子操作,那么就需要在文档中说明需要获得哪些锁才能实现安全的原子操作;如果使用锁来保护状态,那么也要将其写入文档以便日后维护;如果要使用复杂的方法来维护线程安全性,那么一定要将它们写入文档,因为维护者通常很难发现它们。

被折叠的 条评论
为什么被折叠?



