Java多线程 happens-before九大规则

   日期:2020-09-07     浏览:156    评论:0    
核心提示:文章目录happens-before所有规则1. 单线程规则2. 锁操作 (synchronized 和 lock)3.volatile 变量4.线程启动5. 线程join6. 传递性7.中断8. 构造方法9.并发工具类的happens-before原则happens-before所有规则单线程规则锁操作(synchronized 和 lock) 重点volatile 变量 重点线程启动线程join传递性中断构造方法并发工具类的happens-before原则线程安全的容器get

文章目录

      • happens-before所有规则
      • 1. 单线程规则
      • 2. 锁操作 (synchronized 和 lock)
      • 3.volatile 变量
      • 4.线程启动
      • 5. 线程join
      • 6. 传递性
      • 7.中断
      • 8. 构造方法
      • 9.并发工具类的happens-before原则

happens-before所有规则

  1. 单线程规则
  2. 锁操作(synchronized 和 lock) 重点
  3. volatile 变量 重点
  4. 线程启动
  5. 线程join
  6. 传递性
  7. 中断
  8. 构造方法
  9. 并发工具类的happens-before原则
    1. 线程安全的容器get一定能够看得到在此之前put等存入的动作
    2. CountDownLatch
    3. Semaphore
    4. Future
    5. 线程池
    6. CyclicBarrier

1. 单线程规则

在一个线程之内的, 后面的语句, 一定能看到前面的语句做了什么,
例如对于如下的单个线程的赋值语句, 即使下面的a=3 与 b=a 发生了重排序, 但依然能够看得到变量的改变. 因为根据JMM模型. 单个线程使用的是工作内存中的数据.

2. 锁操作 (synchronized 和 lock)

下图有线程A和线程B . 线程A最后一步是解锁, 线程B第一步是加锁.
B加锁之后, 一定能够看得到A线程解锁之前的所有操作.
再例如下图中, 线程A的synchronized 代码块中, 如果释放了锁lock ,那么线程B获得锁之后, 能够看得到线程A操作的所有结构.

3.volatile 变量

关于volatile 修饰的变量, 只要写入修改了值, 那么就一定能够在读取的时候, 读到最新的值
例如此处用volatile修饰的变量, 只要修改了, 那么在打印语句中, 就能获取最新的值.

4.线程启动

如下图所示, 线程a为主线程, 线程b为子线程.
那么在启动线程b,调用start方法的时候, a线程执行的所有语句, 对于线程b都是可见的.

5. 线程join

一旦执行join了, 那么join之后的语句, 一定能够看得到等待的线程执行的所有的语句.
即下图中 ,statement1中的代码, 可以看得到线程b的所有的执行语句.

6. 传递性

如果happens-before A B , 而且 happens-before B C , 那么可以推出 happens-before A C

例如在同一个线程中, 有七行代码, 每两行代码遵循happens-before原则, 即第一行代码运行完了, 第二行就能够看得到, 第二行运行完成了, 第三行就能看得到, 由于有传递性, 那么第一行的代码对于第七行也的能够看得到的.

7.中断

一个线程被其他线程interrupt了, 那么检测中断(isInterrupted) 或者抛出InterruptedException一定看得到. 假设没有happens-before 原则, 那么可能检测是否中断的状态是不对的, 那么可能线程的运行就会很混乱了,

8. 构造方法

对象构造方法的最后一行指令 happens-before于 finalize() 方法的第一行指令 .

9.并发工具类的happens-before原则

  1. 线程安全的容器get一定能够看得到在此之前put等存入的动作. 例如CurrentHashMap在读值的时候, 能够获得到线程中最新的值.
  2. CountDownLatch 作用如下图, 只有执行到67行之后, 54行的wait才能苏醒, 起到闸门的作用
  3. Semaphore: 信号量. 获取许可证, 必须要有人去释放. 如果重排序了, 那么此信号量无作用了. 与CountDownLatch 类似.
  4. Future get方法拿到执行结果, 线程执行完了才能拿得到.
  5. 线程池: 线程池有submit方法用于提交任务. 在提交任务的时候, 可以看到其他线程的所有任务.
  6. CyclicBarrier : 与CountDownLatch 类似, 用于线程流程的控制.
 
打赏
 本文转载自:网络 
所有权利归属于原作者,如文章来源标示错误或侵犯了您的权利请联系微信13520258486
更多>最近资讯中心
更多>最新资讯中心
0相关评论

推荐图文
推荐资讯中心
点击排行
最新信息
新手指南
采购商服务
供应商服务
交易安全
关注我们
手机网站:
新浪微博:
微信关注:

13520258486

周一至周五 9:00-18:00
(其他时间联系在线客服)

24小时在线客服