设计线程安全的类
有时调用是非线程安全的,此时必须把有安全隐患的方法用同步代码块包括起来,所谓线程安全的类就是将同步机制封装在类内部,这样方法调用时就不存在线程安全问题了。
要设计线程安全的类首先寻找可能暴露在外的字段,包括private但是内部方法修改的。然后将这些字段用同步手段保护起来,不仅仅要在修改时保护,在访问时也要保护,以保证时刻读到正确的值。
在保护时注意维护不变性条件,例如当一个类存在缓存机制时,会有版本号和缓存值一一对应的情况,取值时根据版本号取缓存,如果不一致再计算新值并更新版本号,但是这种更新不是完全同步的,多线程下会有两者不一致的情况,此时要把涉及更新的步骤同步起来保证一致。
volatile
volatile并不保证原子性,只保证可见性。所以使用时必须保证对该字段的每次更新都不依赖从前的值,且不构成不变性条件,此时这种保护是足够的。
final
以不可变的方式保证线程安全(对于引用类型必须把它内部的字段全部设置成final才能绝对保证线程安全)
threadlocal
它解决了线程共享的问题,new一个threadlocal方法set一个值再get就能得到,它相当于一个线程私有的容器。
避免this引用溢出
在一个类的构造方法中将this赋值给其他字段,这样其他线程可能获取该字段的值来获取this,一旦获取到this其中的final字段也就变成不安全的,因为对象还没创建完成就能获取到该值(默认0),即使赋值且是final的也无济于事。
除了这种情况以外,还可能造成隐性this引用溢出,在内部类中可以获得外部类的引用,造成危险。要避免这种对象还没创建好时别的线程就可以访问内部的情况。