66.同步访问共享的可变数据
当多个线程共享可变数据的时候, 每个读或写数据的线程都必须执行同步, 如果没有同步, 就无法保证一个线程所做的修改可以被另一个线程获知. 未能同步共享可变数据会造成程序的活性失败和安全性失败.
补充: i++操作是线程不安全的, 因为操作是非原子性的, 应该用原子类的方法
67.避免过度同步
为了避免死锁和数据破坏, 千万不要在同步区域调用外来方法, 更为一般的讲, 要尽量限制同步区域内部的工作量 .
68.executor和task优先于线程
69.并发工具优先于wait和notify
70.线程安全性的文档化
71. 慎用延迟初始化
建议”除非绝对必要, 否则就不要这么做”, 延迟初始化降低了初始化类或者创建实例的开销, 却增加了访问被延迟初始化的域的开销.
如果出于性能的考虑需要对静态域使用延迟初始化, 就是用 lazy initialization holder class 模式.
/**
* 延迟初始化, 只有第一次调用getInstance时, LazyLoad才被初始化
*/
public class LazyLoad {
private LazyLoad() {
}
private static final LazyLoad instance = new LazyLoad();
public LazyLoad getInstance() {
return LazyLoad.instance;
}
}
如果处于性能的考虑而需要要对实力域使用延迟初始化, 就使用双重检查模式
/**
* 双重检查延迟初始化
*/
public class DoubleCheckLazyLoad {
private DoubleCheckLazyLoad() {
}
private static volatile DoubleCheckLazyLoad instance;
public static DoubleCheckLazyLoad getInstance() {
if(instance==null){
synchronized (DoubleCheckLazyLoad.class){
if (instance == null) {
instance = new DoubleCheckLazyLoad();
}
}
}
return instance;
}
}