一、不可变对象
1.不可变对象需要满足的条件:
- 对象创建后其状态就不能修改
- 对象所有域都是final类型
- 对象是正确创建的(在对象创建期间,this引用没有逸出)
2.final关键字:类、方法、变量
3.其他不可变方式:
Collections.unmodifiableXXX:Collection、List、Set、Map...
Guava:ImmutableXXX:Collection、List、Set、Map...
二、线程封闭
1.Ad-hoc线程封闭:程序控制实现,最糟糕,忽略;
2.堆栈封闭:局部变量,无并发问题;
3.ThreadLocal线程封闭:特别好的封闭方法。
三、线程不安全类与写法
1.StringBuilder->StringBuffer:StringBuffer使用synchronized,性能有所损耗。StringBuilder使用在局部变量效果更好,即堆栈封闭。
2.SimpleDateFormate->JodaTime:SimpleDateFormate不是一个线程安全的对象,解决方法可以是堆栈封闭。实际处理日期更推荐JodaTime,对比SimpleDateFormate线程安全,也有其他优势。
3.ArrayList、HashSet、HashMap等Collections
4.先检查再执行:if(condition(a)){handle(a);}:线程不安全写法。
四、同步容器
同步容器不一定线程安全。
1.ArrayList->Vector,Stack:
2.HashMap->HashTable
3.Collections.synchronizedXXX(List,Set,Map)
在使用foreach或者迭代器循环集合时,避免在操作时做remove相关的更新,可以先打标记后删除。多线程时,可以使用synchronized或者lock做迭代,也可以使用并发容器。
五、并发容器 J.U.C
1.ArrayList->CopyOnWriteArrayList:适合读多写少。
2.HashSet、TreeSet->CopyOnWriteArraySet、ConcurrentSkipListSet:对于SkipList使用批量操作时,需要手动同步,操作不是原子性的。
3.HashMap、TreeMap->ConcurrentHashMap、ConcurrentSkipListMap:ConcurrentHashMap不允许空值;ConcurrentSkipListMap的key值有序,支持更高并发。
网友评论