首页 > 代码库 > EFFECTIVE JAVA 第十章 并发

EFFECTIVE JAVA 第十章 并发

 

EFFECTIVE  JAVA  第十章  并发

 

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

  *java语言规范保证读或写一个变量是原子的(可以保证返回的值是某个线程保存在该变量中的),除非这个变量的类型为long或double。(但并不保证一个线程写入的值对于另一个线程是可见)

  *synchronized修饰方法、synchronized代码块可以实现同步

  *volatile修饰的变量只保证读取的是主存里最新的值而不是内存中该值的拷贝,使用volatile变量必须遵循(即变量真正独立于其他变量和自己以前的值),此时在考虑性能提升下代替synchronized关键字

 

67.避免过度同步

  *过度同步可能会导致性能降低、死锁,甚至不确定的行为。

  *不要在同步方法或同步代码快中调用外来不确定的方法,可能会导致异常,死锁或数据损坏。

  *应该在同步区域内做尽可能少的工作。

 

68.executor和task优先于线程

  *java.util.concurrent包中提供了很多高并发的工具类

  

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

  *如果必须使用wait和notify的代码,务必确保始终利用标准模式从while循环内部调用wait。应该优先使用notifyAll而不是notify。

 

70.线程安全性的文档化

 

71.慎用延迟初始化

  *延迟初始化是一把双刃剑,除非必要(初始化这个域开销很大),否则不要这么做

  *多线程访问延迟初始化对象有两种处理方式

 

public static synchronized getInstance(){          if(instance==null){              return new Instance();          }          return instance;}public static getInstance(){          if(instance==null){               synchronized(this){                      if(instance==null){                            return new Instance();                       }                }            }          return instance;}

 

 

 

72.不要依赖于线程调度器scheduler

  *线程调度器依赖于操作系统所采用的策略,不利于程序的移植

  *编写健壮、良好的、可移植的多线程程序,最好的办法是确保可运行线程的平均数量不明显多于处理器的数量

  *让每个执行的线程做些有意义的工作,而不是一直处于等待状态

  *线程优先级是java平台上最不可移植的特征(Thread.sleep()、Thread.yield()一般用于测试)

 

73.避免使用线程组ThreadGroup)

  *线程组并没有提供太多有用的功能,而且它们提供的许多功能还都是有缺陷的。可以忽略掉它,如果你需要处理线程的逻辑组,或许应该使用线程池executor。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

EFFECTIVE JAVA 第十章 并发