线程安全策略
-
将对象设置成不可变对象
- 不可变对象创建需要的条件
- 对象创建后其状态就不能修改
- 对象的所有域都是final类型
- 对象是正确创建的(对象创建时,this引用没有逸出)
- 参考String
- final关键字
- 修饰类:不能被继承,类中的方法都会是final。
- 修饰方法:
- 锁定方法不能被继承类修改
- 效率高
- 一个类的private方法会被隐式的指定为final方法
- 修饰变量:
- 基本的数据类型:初始化之后便不能再修改
- 引用类型变量:初始化之后便不能再指向另外一个对象
- Collections.unmodifiableXXX:Collection,List,Set,Map…
- Guava: ImmutableXXX: Collection,List,Set,Map…
- 不可变对象创建需要的条件
-
线程封闭
df: 将线程封闭到一个线程内,只有一个线程才能看到
- Ad-hoc 线程封闭:程序控制实现,最糟糕,忽略
- 堆栈封闭:局部变量,无并发问题(全局变量容易引起并发问题)
- ThreadLocal 线程封闭
- 数据库对应连接JDBC Connection对象
-
线程不安全类与写法
- StringBuilder: 线程不安全
- StringBuffer: 线程安全
- StringBuffer线程安全是因为方法加了synchronized关键字,所以对象操作都是线程安全的
- 因为加了synchronized关键字,则只能同一时间只能单线程运行,所以运行效率低
- SimpleDateFormat:线程不安全
- JodaTime:线程安全
- Collections
- ArrayList: 线程不安全
- HashSet: 线程不安全
- HashMap: 线程不安全
- 写法
- 先检查再执行 非原子性更新
// 判断条件是否满足a if(condition(a)){ // 对a进行操作 handle(a); // 加锁或者将a变为原子性的 }
-
线程安全–同步容器
- ArrayList -> Vector,Stack
- HashMap -> HashTable(key,value不能为null)
- Collections.synchronizedXXX(List,Set,Map)