Juc11_Java内存模型之JMM、八大原子操作、三大特性、读写过程、happens-before(三)

简介: ⑤. JVMM规范下,多线程先行发生原则之happens-before①. 先行发生原则说明②. happens-before总原则③. happens-before之8条④. 案例说明

⑤. JVMM规范下,多线程先行发生原则之happens-before


①. 先行发生原则说明



①. 如果Java内存模型中有序性仅靠volatile和synchronized来完成,那么有很多操作都将会变得非常啰嗦,但是我们在编写Java并发代码的时候并没有察觉到这一点


②. 我们没有时时、处处、次次,添加volatile和synchronized来完成程序,这是因为Java语言中JMM原则下,有一个"先行发生"(Happens-Before)的原则限制和规则


③. 在JMM中,如果一个操作执行的结果需要对另一个操作可见性或者代码重排序,那么这两个操作之间必须存在happens-before关系


④. x、y案例说明


微信图片_20220107182909.png


②. happens-before总原则


①. 如果一个操作happens-before另一个操作,那么第一个操作的执行结果对第二个操作可见,而且第一个操作的执行顺序排在第二个操作之前(可见性,有序性)


②. 两个操作之间存在happens-before关系,并不意外着一定要按照happens-before原则制定的顺序来执行。如果重排序之后的执行结果与按照happens-before关系来执行的结果一致,那么这种重排序并不非法(可以指令重排)


(值日:周一张三周二李四,假如有事情调换班可以的1+2+3=3+2+1)


③. happens-before之8条


①. 次序规则


一个线程内,按照代码顺序,写在前面的操作先行发生于写在后面的操作(强调的是一个线程)


前一个操作的结果可以被后续的操作获取。将白点就是前面一个操作把变量X赋值为1,那后面一个操作肯定能知道X已经变成了1


②. 锁定规则


(一个unlock操作先行发生于后面((这里的"后面"是指时间上的先后))对同一个锁的lock操作(上一个线程unlock了,下一个线程才能获取到锁,进行lock))


③. volatile变量规则


(对一个volatile变量的写操作先行发生于后面对这个变量的读操作,前面的写对后面的读是可见的,这里的"后面"同样是指时间是的先后)


④. 传递规则


(如果操作A先行发生于操作B,而操作B又先行发生于操作C,则可以得出A先行发生于操作C)


⑤. 线程启动规则(Thread Start Rule)


(Thread对象的start( )方法先行发生于线程的每一个动作)


⑥. 线程中断规则(Thread Interruption Rule)


对线程interrupt( )方法的调用先发生于被中断线程的代码检测到中断事件的发生

可以通过Thread.interrupted( )检测到是否发生中断


⑦. 线程终止规则(Thread Termination Rule)


(线程中的所有操作都先行发生于对此线程的终止检测)


⑧. 对象终结规则(Finalizer Rule)


(对象没有完成初始化之前,是不能调用finalized( )方法的 )


④. 案例说明


①. 代码展示、问题暴露、解决方案


  private int value=0;
  public void setValue(){
      this.value=value;
  }
  public int getValue(){
      return value;
  }


微信图片_20220107183009.png


②. 解决方案


把getter/setter方法都定义synchronized方法(某一时刻只能有一个线程进入)

把value定义为volatile变量,由于setter方法对value的修改不依赖value的原值,满足volatile关键字的使用


(对一个volatile变量的写操作先行发生于后面对这个变量的读操作,前面的写对后面的读是可见的,这里的"后面"同样是指时间是的先后)


相关文章
|
2天前
|
存储 Java 数据库连接
Java堆栈内存管理与优化技巧的实践指南
Java堆栈内存管理与优化技巧的实践指南
|
1天前
|
存储 监控 算法
Java内存管理策略与性能调优
Java内存管理策略与性能调优
|
1天前
|
存储 缓存 算法
深入分析Java中的内存管理与垃圾回收机制
深入分析Java中的内存管理与垃圾回收机制
|
2天前
|
安全 Java
解决Java中集合类的内存占用问题
解决Java中集合类的内存占用问题
|
2天前
|
存储 监控 算法
Java中的内存泄漏问题及其解决方法
Java中的内存泄漏问题及其解决方法
|
2天前
|
缓存 监控 Java
Java中的内存泄漏及其排查方法
Java中的内存泄漏及其排查方法
|
2天前
|
Java API 数据处理
Java 8的新特性详解
Java 8的新特性详解
|
2天前
|
Java 机器人 程序员
优化Java中文件读写的性能策略
优化Java中文件读写的性能策略
|
9天前
|
存储 Java C++
Java虚拟机(JVM)管理内存划分为多个区域:程序计数器记录线程执行位置;虚拟机栈存储线程私有数据
Java虚拟机(JVM)管理内存划分为多个区域:程序计数器记录线程执行位置;虚拟机栈存储线程私有数据,如局部变量和操作数;本地方法栈支持native方法;堆存放所有线程的对象实例,由垃圾回收管理;方法区(在Java 8后变为元空间)存储类信息和常量;运行时常量池是方法区一部分,保存符号引用和常量;直接内存非JVM规范定义,手动管理,通过Buffer类使用。Java 8后,永久代被元空间取代,G1成为默认GC。
22 2
|
12天前
|
存储
数据在内存中的存储(2)
数据在内存中的存储(2)
25 5