66.同步访问共享的可变数据

当多个线程共享可变数据的时候, 每个读或写数据的线程都必须执行同步, 如果没有同步, 就无法保证一个线程所做的修改可以被另一个线程获知. 未能同步共享可变数据会造成程序的活性失败和安全性失败.

补充: i++操作是线程不安全的, 因为操作是非原子性的, 应该用原子类的方法

67.避免过度同步

为了避免死锁和数据破坏, 千万不要在同步区域调用外来方法, 更为一般的讲, 要尽量限制同步区域内部的工作量 .

68.executor和task优先于线程

69.并发工具优先于wait和notify

70.线程安全性的文档化

71. 慎用延迟初始化

建议”除非绝对必要, 否则就不要这么做”, 延迟初始化降低了初始化类或者创建实例的开销, 却增加了访问被延迟初始化的域的开销.
如果出于性能的考虑需要对静态域使用延迟初始化, 就是用 lazy initialization holder class 模式.

  1. /**
  2. * 延迟初始化, 只有第一次调用getInstance时, LazyLoad才被初始化
  3. */
  4. public class LazyLoad {
  5. private LazyLoad() {
  6. }
  7. private static final LazyLoad instance = new LazyLoad();
  8. public LazyLoad getInstance() {
  9. return LazyLoad.instance;
  10. }
  11. }

如果处于性能的考虑而需要要对实力域使用延迟初始化, 就使用双重检查模式

  1. /**
  2. * 双重检查延迟初始化
  3. */
  4. public class DoubleCheckLazyLoad {
  5. private DoubleCheckLazyLoad() {
  6. }
  7. private static volatile DoubleCheckLazyLoad instance;
  8. public static DoubleCheckLazyLoad getInstance() {
  9. if(instance==null){
  10. synchronized (DoubleCheckLazyLoad.class){
  11. if (instance == null) {
  12. instance = new DoubleCheckLazyLoad();
  13. }
  14. }
  15. }
  16. return instance;
  17. }
  18. }

72. 不要依赖线程调度器

73.避免使用线程组