多线程设计模式
TODO
Single Threaded Execution 模式
同一时间内只能让一个线程执行处理。
synchronized标记方法。
synchronized标记方法。STE模式下存在一个共享资源类,包含 safeMethod 和 unsafeMethod ,并会保护不安全的方法。
何时使用STE
多线程访问:共享资源类的实例可能被多个线程同时访问时。
共享资源类实例的状态可能发生变化时。
需要确保安全性时。(Java集合类大多为非线程安全)
STE分析
生存性
死锁危险,此时:
存在多个共享资源角色
线程在持有某个共享资源角色的锁时,获取其他角色的锁
获取共享资源角色的锁顺序不固定
可复用性
多线程下的继承,如果共享资源类子类存在 unsafeMethod ,则会影响父类的安全性。(继承反常)
临界区及性能
临界区:只允许单个线程执行的程序。
STE模式会降低性能,原因:
获取锁需要处理时间
线程冲突导致等待

细节和习题
使
unlock不被return和异常处理打断。

注意选对获取锁的实例
引用类型、int、char等基本类型的赋值和引用操作是原子的,而long、double类型的赋值和引用是非原子操作。

Immutable 模式
示例类
只含
get方法不含set方法的类如果
getter的实现不常规,如返回StringBuffer,则外部可能修改实例内容。类字段声明为
private final
当使用需频繁访问的共享实例时,Immutable模式下的类不需要使用synchronized进行保护,性能较高。
StringBuffer类和String类是成对的mutable和immutable类,前者可随便改写字符串(为确保安全,需妥善使用synchronized),后者不可改写,但引用的速度更快。二者通过构造函数,可互相转换。
final关键字
无法创建final类的子类(无法拓展)
final实例方法不会被子类的方法重写;静态final方法表示不会被子类的方法隐藏。
final字段只可被赋值一次
对final实例字段:声明时或构造函数中赋值
对final静态字段:声明时或静态初始化代码块中赋值
集合类与多线程
Collections.synchronizedList
ArrayList是线程不安全的类,改进如下:
final List<Integer> list = Collections.synchronizedList(new ArrayList<Integer>());
进行“写”,无需多加处理;对于“读”,需要额外同步:
copy-on-write
java.util.concurrent.CopyOnWriteArrayList类使用“写时复制”机制,确保安全的数组被整体复制,无需担心迭代器依次读取元素时元素被修改。
习题
参考: 《图解Java多线程设计模式》
最后更新于
这有帮助吗?