Java多线程 happens-before九大规则

文章目录

      • 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. 单线程规则

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

2. 锁操作 (synchronized 和 lock)

下图有线程A和线程B . 线程A最后一步是解锁, 线程B第一步是加锁.
B加锁之后, 一定能够看得到A线程解锁之前的所有操作.
Java多线程 happens-before九大规则_第3张图片再例如下图中, 线程A的synchronized 代码块中, 如果释放了锁lock ,那么线程B获得锁之后, 能够看得到线程A操作的所有结构.
Java多线程 happens-before九大规则_第4张图片

3.volatile 变量

关于volatile 修饰的变量, 只要写入修改了值, 那么就一定能够在读取的时候, 读到最新的值
Java多线程 happens-before九大规则_第5张图片例如此处用volatile修饰的变量, 只要修改了, 那么在打印语句中, 就能获取最新的值.
Java多线程 happens-before九大规则_第6张图片

4.线程启动

如下图所示, 线程a为主线程, 线程b为子线程.
那么在启动线程b,调用start方法的时候, a线程执行的所有语句, 对于线程b都是可见的.
Java多线程 happens-before九大规则_第7张图片

5. 线程join

一旦执行join了, 那么join之后的语句, 一定能够看得到等待的线程执行的所有的语句.
即下图中 ,statement1中的代码, 可以看得到线程b的所有的执行语句.
Java多线程 happens-before九大规则_第8张图片

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才能苏醒, 起到闸门的作用
    Java多线程 happens-before九大规则_第9张图片
  3. Semaphore: 信号量. 获取许可证, 必须要有人去释放. 如果重排序了, 那么此信号量无作用了. 与CountDownLatch 类似.
  4. Future get方法拿到执行结果, 线程执行完了才能拿得到.
  5. 线程池: 线程池有submit方法用于提交任务. 在提交任务的时候, 可以看到其他线程的所有任务.
  6. CyclicBarrier : 与CountDownLatch 类似, 用于线程流程的控制.

你可能感兴趣的:(Java多线程基础与核心)