happen-before
阿里云国内75折 回扣 微信号:monov8 |
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6 |
happen-before
什么是happen-before
JMM可以通过happens-before关系向程序员提供跨线程的内存可见性保证(如果A线程的写操作a与B线程的读操作b之间存在happens-before关系尽管a操作和b操作在不同的线程中执行但JMM向程序员保证a操作将对b操作可见).
JMM就是Java内存模型(java memory model)。因为在不同的硬件生产商和不同的操作系统下内存的访问有一定的差异所以会造成相同的代码运行在不同的系统上会出现各种问题。所以java内存模型(JMM)屏蔽掉各种硬件和操作系统的内存访问差异以实现让java程序在各种平台下都能达到一致的并发效果。
Java内存模型规定所有的变量都存储在主内存中包括实例变量静态变量但是不包括局部变量和方法参数。每个线程都有自己的工作内存线程的工作内存保存了该线程用到的变量和主内存的副本拷贝线程对变量的操作都在工作内存中进行。线程不能直接读写主内存中的变量。
不同的线程之间也无法访问对方工作内存中的变量。线程之间变量值的传递均需要通过主内存来完成。
这里借用一下这两张图方便理解jmm
要解决这个问题就需要把变量声明为 volatile 这就指示 JVM这个变量是共享且不稳定的每次使用它都到主存中进行读取。
具体原则
- 程序顺序规则一个线程中的每个操作happens-before于该线程中的任意后续操作。
- 监视器锁规则对一个锁的解锁happens-before于随后对这个锁的加锁。
- volatile变量规则对一个volatile域的写happens-before于任意后续对这个volatile域的读。
- 传递性如果A happens-before B且B happens-before C那么A happens-before C。
- 线程启动规则假定线程A在执行过程中通过执行ThreadB.start()来启动线程B那么线程A对共享变量的修改在接下来线程B开始执行前对线程B可见。注意线程B启动之后线程A在对变量修改线程B未必可见。
- 线程中断规则线程t1写入的所有变量在任意其它线程t2调用t1.join()或者t1.isAlive() 成功返回后都对t2可见。。
- 线程终止规则线程t1写入的所有变量调用Thread.interrupt()被打断的线程t2可以看到t1的全部操作。
- 对象finalize规则一个对象的初始化完成构造函数执行结束先行于发生它的finalize()方法的开始。