[JMM]__JMM中引用类型final域重排序规则

对于final域为引用类型的情况:

1,在构造函数内,对于一个final域为引用类型及对其引用的对象的成员变量的写入,与随后在构造函数外将被构造的对象赋值给另一引用变量,这2个操作不能被重排序.

如下图详解:

时间: 2024-08-01 00:13:21

[JMM]__JMM中引用类型final域重排序规则的相关文章

[JMM]__JMM中的普通final域重排序规则

关于final域,编译器和处理器遵循2个重排序规则: 1,在构造函数内部,对final域的成员变量的写入,与随后将这个被构造的对象赋值给另一个引用变量,这2个操作不能重排序 2,初次读一个包含final域的对象的引用,与随后读这个final域,这2个操作之间不能重排序. 上面的重排序规则能保证,在对象的引用在被任何线程可见之前,该对象中的final域已经被正确初始化了.而普通域 不具有这个保障. 即,在对象引用被其他线程可见时,该对象可能还未构造完成,即其中的普通域由于被重排序到构造函数之外,此

Java并发编程之final域的内存语义

一.final域的重排序规则 对于final域,编译器和处理器要遵循两个重拍序规则: 1.在构造函数内对一个final域的写入,与随后把这个被构造对象的引用赋值给一个引用变量,这两个操作之间不能重排序. 2.初次读一个包含final域的对象的应用,与随后初次读这个final域,这两个操作之间不能重排序 下面通过一个示例来分别说明这两个规则: public class FinalTest { int i;//普通变量 final int j; static FinalTest obj; publi

Java并发编程原理与实战四十四:final域的内存语义

一.final域的重排序规则 对于final域,编译器和处理器要遵循两个重拍序规则: 1.在构造函数内对一个final域的写入,与随后把这个被构造对象的引用赋值给一个引用变量,这两个操作之间不能重排序. 2.初次读一个包含final域的对象的应用,与随后初次读这个final域,这两个操作之间不能重排序 下面通过一个示例来分别说明这两个规则: public class FinalTest { int i;//普通变量 final int j; static FinalTest obj; publi

Java并发拾遗(一)——并发、JMM与重排序

一.并发中的关键问题及其解决思路 并发中的关键问题:1. 线程之间如何通信 -- 线程之间如何交换信息2. 线程之间如何同步 -- 控制线程的相对执行顺序 两种解决思路: 1. 隐式通信,显示同步 -- 线程之间通过共享内存中的公共状态来隐式通信,那么就必须显示的指定线程见的互斥来实现同步2. 显式通信,隐式同步 -- 线程之间无公共状态,通过明确的发送消息进行通信,那么由于消息的发送在消息接收之前,就可以实现隐式的同步 Java选择了共享内存的方式来解决并发中的两个关键问题,因此Java中线程

Java内存模型-final域的内存语义

一 引言 说到final你肯定知道它是Java中的关键字,那么它所在Java中的作用你知道吗?不知道的话,请前往这篇了解下https://www.cnblogs.com/yuanfy008/p/8021673.html 今天我们来说说final域在JMM中的内存语义. 二 final域的重排序规则 开门见山,对于final域,编译器和处理器一定要遵守两个重排序规则(JSR-133才增强了final域): 1)在构造函数内对一个final域的写入,与随后把这个被构造对象的引用赋值给一个引用变量,这

Java并发编程原理与实战四十一:重排序 和 happens-before

一.概念理解 首先我们先来了解一下什么是重排序:重排序是指编译器和处理器为了优化程序性能而对指令序列进行重新排序的一种手段. 从Java源代码到最终实际执行的指令序列,会分别经历下面3种重排序,如下图所示 上述的1属于编译器重排序,2和3属于处理器重排序.这些重排序可能会导致多线程程序出现内存可见性问题.在单线程程序中,对存在控制依赖的操作重排序,不会改变执行结果(这也是as-if-serial语义允许对存在控制依赖的操作做重排序的原因):但在多线程程序中,对存在控制依赖的操作重排序,可能会改变

java内存模型之重排序

1.重排序 在执行程序时为了提高性能,编译器和处理器常常会对指令做重排序.重排序分三种类型: 1.编译器优化的重排序.编译器在不改变单线程程序语义的前提下,可以重新安排语句的执行顺序. 2.指令级并行的重排序.现代处理器采用了指令级并行技术(Instruction-Level Parallelism, ILP)来将多条指令重叠执行.如果不存在数据依赖性,处理器可以改变语句对应机器指令的执行顺序. 3.内存系统的重排序.由于处理器是使用缓存和读/写缓冲区,这使得加载和存储操作看上去可能是乱序执行.

深入理解 Java 中的 final 关键字

final 是Java 中重要关键字之一,可以应用于类.方法以及变量上.这篇文章中将讲解什么是 final 关键字?将变量.方法和类声明为 final 代表了什么?使用 final 的好处是什么? final 关键字是什么? final 在 Java 中是一个保留的关键字,可以声明成员变量.方法.类以及本地变量.一旦你将引用声明作 final,你将不能改变这个引用了,编译器会检查代码,如果试图将变量再次初始化的话,编译器会报编译错误. final 变量 凡是对成员变量或者本地变量(在方法中的或者

Java的多线程机制系列:不得不提的volatile及指令重排序(happen-before)

一.不得不提的volatile volatile是个很老的关键字,几乎伴随着JDK的诞生而诞生,我们都知道这个关键字,但又不太清楚什么时候会使用它:我们在JDK及开源框架中随处可见这个关键字,但并发专家又往往建议我们远离它.比如Thread这个很基础的类,其中很重要的线程状态字段,就是用volatile来修饰,见代码 /* Java thread status for tools, * initialized to indicate thread 'not yet started' */   p