建立和理解Java 并发的基础

来源:互联网 发布:idea2016新建java项目 编辑:程序博客网 时间:2024/05/29 07:33

整理内容---部分来自书籍,部分来自网络 。

Happens-before 和 synchronizes-with是用来建立和理解Java 并发的基础 。

  • HAPPENS-BEFORE:这个关系用来指示“一段代码在其他代码开始执行前已经完全执行完毕”。
  • SYNCHRONIZES-WITH:这个关系表示一个行为在发生时,它首先把要操作的那些对象同主存同步完毕之后才继续执行。

HAPPENS-BEFORE

  HAPPENS-BEFORE:Java内存模型中定义的两项操作之间的偏序关系,如果操作A先行发生于操作B,其实就是说在发生操作B之前,操作A产生的影响能被操作B观察到。“影响”包括修改了内存中共享变量的值,发送了消息,调用了方法等。

  1. 程序次序规则:在一个线程内,按照代码控制流顺序,在前面的操作先行发生于后面的操作。
  2. 管程锁定规则:一个unlock操作先行发生于后面对同一个锁的lock操作。
  3. Volatile变量规则:对一个volatile变量的写操作先行发生于后面对这个变量的读操作。
  4. 线程启动规则:Thread对象的start()方法先行发生于此线程的每个操作。
  5. 线程终止规则:线程中的所有操作都先行发生于对此线程的终止检测。
  6. 线程中断规则:对线程的interrupt()方法的调用先行发生于被中断线程的代码检测中断事件的发生。
  7. 对象终结过则:一个对象的初始化完成先行发生于它的finalize()方法的开始。
  8. 传递性:如果操作A先行发生于操作B,操作B现象发生于操作C,那么就可以得出操作A先行发生于操作C的结论。

  时间上的先后顺序与先行发生原则之间基本上没有太大的关系。所以,在衡量并发安全问题的时候不要受到时间顺序的干扰,一切都以先行发生原则为准。

SYNCHRONIZES-WITH

      线程对变量的所有操作(读取,赋值等)都必须在工作内存中进行,而不能直接读写主内存的变量。不同的线程之间也无法直接访问对方工作内存中的变量,线程间变量值的传递均需要通过主内存来完成。线程不能直接为主存中中字段赋值,它会将值指定给工作内存中的变量副本(assign),完成后这个变量副本会同步到主存储区(store-write),至于何时同步过去,根据JVM实现系统决定.