前面介绍了那么多,那么我们在平时编程的时候应该如何保证我们的代码能够安全的执行呢?
安全策略
-
不可变对象
- 只要对象创建完成,那么这个对象就是一个线程安全对象,因为不可变,所以没有线程可以修改他,条件归结为一下两点:
- 对象创建以后不能修改;
- final修饰:
- 非容器对象由final修饰,设置为私有,不提供setter方法;
- 原生的不可修改(本质还是final修饰);
- Collections.unmodifiableXxx(Xxx: Collection,List,Set,Map);
- Guava:ImmutableXxx(Xxx: Collection,List,Set,Map);
- final修饰:
- 对象是正确创建的;
- 对象创建期间没有逸出;
- 对象创建以后不能修改;
- 只要对象创建完成,那么这个对象就是一个线程安全对象,因为不可变,所以没有线程可以修改他,条件归结为一下两点:
-
ThreadLocal的线程安全问题
- 解决线程内变量的共享的问题;
-
Synchronized同步容器线程安全问题
- ArrayList 换用 Vector、Stack
- HashMap 换用 HashTable(Key和Value不能为null)
- Collections.synchronizedXxx(<list-set-map>)
-
JUC并发容器线程安全问题
- ArrayList 换用 CopyOnWriteArrayList
- HashSet 换用 CopyOnWriteArraySet
- TreeSet 换用 ConcurrentSkipListSet
- HashMap 换用 ConcurrentHashMap(Key和Value不能为null)
- TreeMap 换用 ConcurrentSkipListMap
-
多线程环境下,尽量少用线程不安全的类
- StringBuilder 换用 StringBuffer
- SimpleDateFormat 换用 Joda-Time框架的DateTime
- ArrayList、HashSet、HashMap
网友评论