final域的内存语义

并发编程系列之Final域的内存语义 前言 上节我们讲了锁的内存语义,在同步原语中我们已经讲了两个,今天再来介绍另一个同步原语Final域,了解下final域的内存语义以及重排序规则在处理器中又是如何实现的,并结合前面的volatile和锁,大家可以进行对比下,OK,开始我们今天的并发之旅吧。 final域的重排序规则 对于final域,编译器和处理器需要遵循两个重排序规则: 对一个构造函数内final域的写入,与后续把这个构造对象的引用赋值给一个引用变量,这2个操作之间是不能重排序的,相当于对一个final域的写和读不能重排序 阅读详情

与前面介绍的锁和volatile相比,对final域的读和写更像是普通的变量访问。下面将介绍final域的内存语义

1.final域的重排序规则

  对于final域,编译器和处理器要遵守两个重排序规则。
1)在构造函数内对一个final域的写入,与随后把这个被构造对象的引用赋值给一个引用变量,这两个操作之间不能重排序。
2)初次读一个包含final域的对象的引用,与随后初次读这个final域,这两个操作之间不能重排序。
  下面通过一个实例说明这两个规则

public class FinalExample {
	
	int i;			// 普通变量
	final int j;	// final变量
	
	static FinalExample obj;
	
	public FinalExample() {	// 构造函数
		i = 1;				// 写普通域
		j = 2;				// 写final域
	}
	
	public static void writer() {	// 写线程A执行
		obj = new FinalExample();
	}
	
	public static void reader() {	// 读线程B执行
		FinalExample object = obj;	// 读对象引用
		int a = object.i;			// 读普通域
		int b = object.j;			// 读final域
	}

}

  这里假设一个线程A执行writer()方法,随后另一个线程B执行reader()方法,下面我们通过这两个线程的交互来说明这两个规则。

1.1写final域的重排序规则

  写final域的重排序规则禁止把final域的写重排序到构造函数之外。这个规则的实现包含2个方面。
1)JMM禁止编译器把final域的写重排序到构造函数之外,
2)编译器会在final域的写之后,构造函数return之前,插入一个StoreStore屏障。这个屏障禁止禁止处理器把final域的写重排序到构造函数之外。

1.2读final域的重排序规则

  读final域的重排序规则是,在一个线程中,初次读对象引用与初次读该对象包含的final域,JMM禁止处理器重排序这两个操作。编译器会在读final域操作之前插入一个LoadLoad屏障。
  初次读对象引用与初次读对象包含的final域,这两个操作之间存在间接依赖关系。由于编译器遵守间接依赖关系,因此编译器不会重排序这两个操作。

2.final域为引用类型

  上面我们看到的final域是基础数据类型,如果final域是引用类型,将会有什么效果呢?

public class FinalReferenceExample {
	final int [] intArray;
	static FinalReferenceExample obj;
	
	public FinalReferenceExample () {			// 构造函数
		intArray = new int[1];					// 1
		intArray[0] = 1;						// 2
	}

	public static void writerOne() {			// 写线程A执行
		obj = new FinalReferenceExample();		// 3
	}

	public static void writerTwo() {			// 写线程B执行
		obj.intArray[0] = 2;					// 4
	}
	
	public static void reader() {				// 读线程C执行
		if (obj != null) {						// 5
			int tmep1 = obj.intArray[0];		// 6
		}
	}

}

  本例final域为一个引用类型,他引用一个int型的数组对象。对于引用类型,写final域的重排序规则对编译器和处理器增加了如下约束:在构造函数内对一个final引用的对象的成员域的写入,与随后在构造函数外把这个被构造对象引用赋值给一个引用变量,这个两个操作之间不能重排序。

3.JSR-133对final的语义的增强

  在旧的Java内存模型中,一个最严重的缺陷就是线程可能看到final域的值会改变。比如一个线程当前看到一个整型final域的值为0,过一段时间之后这个线程再去读这个final域的值时,却发现值变为1,。最常见的例子就是在旧的Java内存模型值,String的值可能会改变。
  为了修补这个漏洞,JSR-133专家组增强了final的语义。通过为final域增加写和读重排序,可以为Java程序员提供初始化安全保证:只要对象是正确构造的,那么不需要使用同步就可以保证任意线程都能看到这个final域在构造函数中被初始化之后的值。


手把手教你用ES8311芯片搞定智能音箱TTS播放(附完整寄存器配置清单) 本文详细介绍了如何使用ES8311音频编解码芯片实现智能音箱TTS播放功能,包括芯片特性、硬件连接、寄存器配置及调试技巧。通过完整的寄存器配置清单和实战经验,帮助开发者快速掌握ES8311在智能音箱中的应用,优化音频输出质量和低功耗设计。 阅读详情

相关推荐

百度智能云ASR实战:5分钟搞定Unity语音转文字(含完整代码)

本文详细介绍了如何在Unity中集成百度智能云ASR服务,实现高效的语音转文字功能。从环境配置、音频处理到服务端通信,提供完整代码示例和实战优化技巧,帮助开发者快速实现语音交互功能,适用于游戏开发、XR应用等场景。

ujm56789012的博客 215

java final域_java内存模型之-final域

1.1final域的重排序规则对于final域,编译器和处理器要遵守两个重排序规则。1)在构造函数内对一个final域的写入,与随后把这个被构造对象的引用赋值给一个引用变量,这两个操作之间不能重排序。2)初次读一个包含final域的对象的引用,与随后初次读这个final域,这两个操作之间不能重排序。1.1.1写final域重排序规则写final域的重排序规则禁止把final域的写重排序到构造函数之...

weixin_31881743的博客 388

安装部署 Guacamole 远程桌面网关

Guacamole 是Apache基金会提供的一组基于web的远程桌面访问工具,支持 VNC、RDP、SSH、 Telnet 等协议,支持远程透传音视频。

UsamaBinLaden6976498的专栏 1963

java final语义_Java final关键字及其内存语义

final是Java中的一个关键字,final可用于修饰类、方法、参数和变量(包括实例变量和类变量)。final修饰类final修饰的类具有不可继承性,也就是如果一个类是final类型的,则这个类不允许有子类。首先我们顶一个final类:public final class FinalClass {private int field;}复制代码然后如果我们尝试去继承这个类的话编译器会报错:publ...

weixin_34707242的博客 263

Apple CarPlay Certification Guide December 2022 解析V1.0

Apple CarPlay Certification Guide December 2022更新说明

m0_74450450的博客 703

Xiaojie雷达之路---毫米波雷达基础知识---角度估计

本篇文章主要介绍毫米波雷达的基础知识中的角度估计,对于本篇文章主要回答5个问题 1.在雷达的前方,如何估计前方一个物体的角度 2.角度测量的准确性 3.如何测量多个物体的角度 4.雷达可测的角度的视场最大值为多少 5.角度分辨率取决于什么因素 文章目录估计雷达前面一个物体的角度角度测量的准确性雷达的最大角视场测量雷达前方多个距离和速度相同的物体角度分辨率角度估计的流程 估计雷达前面一个物体的角度 估计一个物体的角度,最少需要两根接收天线 发射天线发送一个chirp,经过物体发射后信号,信号分别被第一根天

XiaoJie的博客 1万+

final内存语义

final内存语义

qq_41820066的博客 537

YOLOv11改进策略【卷积层】| DEConv: 强度信息与梯度特征融合的细节增强 适用于小目标与细节目标检测任务

本文记录的是利用 模块优化 的目标检测网络模型。(Detail-Enhanced Convolution,细节增强卷积)的设计旨在,解决 目标检测网络中传统普通卷积缺乏目标细节相关先验、对小目标边缘、目标与背景边界等关键细节捕捉能力不足的问题,同时避免引入额外参数量与计算开销,以适配 对实时推理性能与检测精度的双重需求。DEA-Net: Single image dehazing based on detail-enhanced convolution and content-guided atte

Limiiiing的博客 1496

7、final域

final域 final域重排序规则 对于final域,编译器和处理器要遵守两个重排序规则: 1、在构造函数对final域的写入,与随后把这个构造的对象的引用赋值给一个引用变量,这两个操作不能重排序。 2、初次读final域的对象的引用,与随后初次读final域,这两个操作不能重排序。 public class FinalExample { int i; ...

闪电侠-公子的博客 336

人工智能---什么是Transformer?

Transformer是一种强大的神经网络架构,最初由Google的研究人员在论文《Attention is All You Need》中提出,用于自然语言处理任务,特别是在机器翻译方面取得了巨大成功。Transformer的核心思想是完全基于自注意力机制(self-attention mechanism)来实现序列到序列(sequence-to-sequence)的学习。它在自然语言处理(NLP)和其他序列到序列任务中表现出色,逐渐成为该领域的主流模型。近些年也逐渐在自动驾驶领域有所应用。

智能汽车人的博客 3955

数学建模学习(5):最全概率分析之图表绘制详解,内容比较多,建议收藏

(1) 绘制正整数频率使用 tabulate(X) (2)

全栈川川 4591

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

专栏原创出处:源笔记文件 ,源码 1 final域的内存语义 对final域的读和写更像是普通的变量访问。下面将介绍 final域的内存语义。 public class FinalExample { int i; //普通变量 final int j; //final变量 final in...

2.wa 815

Transformer 在自动驾驶中的应用:深度对比特斯拉(Tesla)、小鹏(XNet)、华为(ADS 2.0)在 Transformer 架构应用上的异同

自动驾驶汽车是当前人工智能和机器学习领域的热点研究方向之一。其核心技术之一就是基于深度学习的感知和决策系统。在感知系统中,目标检测和跟踪、语义分割、场景理解等计算机视觉任务至关重要。而在决策系统中,规划和控制模块需要对当前状态进行建模并做出相应的决策。近年来,Transformer模型在自然语言处理领域取得了突破性进展,并逐步被应用到计算机视觉等其他领域。相比于传统的卷积神经网络和循环神经网络,Transformer模型具有建模长距离依赖关系的能力,可以更好地捕捉输入序列中的全局信息。

AI天才研究院 864

【搞定Java并发编程】第11篇:final域的内存语义

上一篇文章:锁的内存语义:https://blog.youkuaiyun.com/pcwl1206/article/details/84921447 目  录: 1、final域的重排序规则 2、写final域的重排序规则 3、读final域的重排序规则 4、final域为引用类型 5、为什么final引用不能从构造函数内“逸出”? 6、final语义在处理器中的实现 7、JSR-133为什么...

Java学习 533

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

java并发:volatile和final域的内存语义

volatile和final域的内存语义1 volatile的内存语义1.1 volatile的特性1.2 happens-before简介1.2.1 happens-before的定义1.3 volatile 写-读建立的happens-before关系1.4 volatile 写-读的内存语义1.5 volatile内存语义的实现2 final域内存语义2.1 final域的重排序规则2.2 写final域的重排序规则2.3 读final域的重排序规则2.4 final域为引用类型2.5 为什么fina

weixin_45490507的博客 300

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

java内存模型 final域的内存语义,happens-before

目录 final域的内存语义 final域的重排序规则 写final域的重排序规则 读final域的重排序规则 final域为引用类型 为什么final引用不能从构造函数内溢出 final语义在处理器中的实现 JSR-133为什么要增强final的语义 happens-before JMM的设计 happens-before的定义 happens-before规则 fi...

今天吃了吗的博客 338

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

java final域_【Java】final 域的内存语义

文章来源:《Java并发编程的艺术》final 域的重排序规则对于 final 域,编译器和处理器要遵守两个重排序规则。1)在构造函数内对一个 final 域的写入,与随后把这个被构造对象的引用赋值给一个引用变量,这两个操作之间不能重排序;2)初次读一个包含 final 域的对象的引用,与随后初次读这个 final 域,这两个操作之间不能重排序。下面通过一些实例性的代码来分别说明这两个规则。pub...

weixin_28789303的博客 161

《Java并发编程的艺术》 读书笔记 之 Java内存模型(六)final域的内存语义

《Java并发编程的艺术》 读书笔记: - - 原作者:方腾飞 final域的内存语义 与前面介绍的锁和volatile相比,对final域的读和写更像是普通的变量访问。下面将介绍final域的内存语义。 (1)、final域的重排序规则 对于final域,编译器和处理器要遵守两个重排序规则。 1)在构造函数内对一个final域的写入,与随后把这个被构造对象的引用赋值给一个引用变...

小哥骑单车 1377

【JVM原理详解】45-final域的内存语义

this逃逸指在构造函数执行期间,this在构造函数中启动线程,并把this传进去在构造函数中注册回调/监听器,回调中引用this在构造函数中把this赋给静态变量或共享集合。

gaochufukanyongren的博客 12

读书笔记-Java并发编程的艺术-第3章(Java内存模型)-第6节(final域的内存语义)

java并发编程的艺术 java内存模型 final域的内存语义

心流时间的博客 1012
上一篇: 锁的内存语义
下一篇: Java中锁的介绍
geek-wmy
博客等级 码龄9年 322粉丝 126原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值