Java面试之Happens-Before原则

news2025/2/23 16:48:24

此篇接上一篇的Java面试之volatile关键字。

首先,这是Java语言中的一个“先行发生”(Happens-Before)的原则。是判断数据是否存在竞争,线程是否安全的非常有用的手段,也是Java内存模型中定义的两项操作之间的偏序关系。

其次,Happens-Before是一种可见性的模型。也就是说,在多线程环境下,原本因为指令重排序的存在会导致数据的可见性问题,也就是A线程修改某个共享变量对B线程不可见。

因此,JMM通过Happens-Before关系向开发人员提供跨越线程的内存可见性保证。如果一个操作的执行结果对另一操作可见,那么这两个操作之间必然存在Happens-Before管理。

注意,Happens-Before关系只是描述结果的可见性,并不表示指令执行的先后顺序,也就是说只要不对结果产生影响,仍然允许指令重排序。

最后,在Java内存模型中有一些“天然的”先行发生关系,这些先行发生关系无须任何同步器协助就已经存在,可以在编码中直接使用。

程序顺序规则(Program Order Rule),在单个线程中,按照程序的顺序,前面的操作Happens-Before于后面的操作。简而言之,如果在代码中操作B出现在操作A之后,那么操作A的结果对操作B是可见的。

程序顺序规则(Program Order Rule)

监视器锁规则(Monitor Lock Rule),一个线程对于一个锁的释放锁操作,一定Happens-Before与后续线程对这个锁的加锁操作。

监视器锁规则(Monitor Lock Rule)

volatile变量规则(Volatile Variable Rule),对volatile变量的写操作Happens-Before于后续对该变量的读操作。

volatile变量规则(Volatile Variable Rule)

线程启动规则(Thread Start Ruler),如果线程A执行操作star(),那么线程A的star()之前的操作Happens-Before线程B中的任意操作。

线程启动规则(Thread Start Ruler)

线程终止规则(Thread Termination Rule),线程中的所有操作都Happens-Before于对此线程的终止检测,我们可以通过join()方法是否结束、isAlive()的返回值等手段检测线程是否已经终止执行。

线程终止规则(Thread Termination Rule)

线程中断规则(Thread Interruption Rule),对线程interrupt()方法的调用Happens-Before于被中断线程的代码检测到中断事件的发生,可以通过interrupted()方法检测到是否有中断发生。

线程中断规则(Thread Interruption Rule)

对象终结规则(Finalizer Rule),一个对象的初始化完成(构造函数执行结束)Happens-Before于它的finalize()方法的开始。

对象终结规则(Finalizer Rule)

传递性(Transitivity),一个线程中的每个操作,Happens-Before这个线程中的任意后续操作,可以简单认为是as-if-serial。也就是不管怎么重排序,单线程的程序的执行结果不能改变传递性规则,也就是A Happens-Before B,B Happens-Before C,就可以推导出A Happens-Before C。

传递性(Transitivity)

synchronized和volatile

首先,两者都是Java中用于实现多线程并发的关键字,它们的作用和使用方式有所不同:

synchronized用于实现线程之间的同步和互斥,可以保证同一时间只有一个线程能够访问被synchronized保护的代码块或方法。

synchronized实现的是一种悲观锁机制,即线程在访问共享资源之前需要先获取锁定标志,这种方式可能会导致多个线程之间的竞争和阻塞,影响系统的性能。

volatile用于实现多线程之间的共享变量,可以保证被v修饰的变量在多个线程之间可见性,即一个线程修改了该变量的值,其他线程能够立即看到该变量的最新值。

volatile实现的是一种乐观锁机制,即线程之间不会产生阻塞和竞争,因此性能更好。

因此,synchronized和v适用于不同的场景和需求:

如果需要保证线程之间的同步和互斥,避免多个线程同时访问共享资源导致数据不一致和安全问题,可以使用synchronized。

如果需要实现多线程之间的共享变量,保证变量的可见性和一致性,并且线程之间不需要互斥和同步,可以使用volatile。



喜欢的朋友记得点赞、收藏、关注哦!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2258912.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

TensorFlow深度学习实战(1)——神经网络与模型训练过程详解

TensorFlow深度学习实战(1)——神经网络与模型训练过程详解 0. 前言1. 神经网络基础1.1 神经网络简介1.2 神经网络的训练1.3 神经网络的应用 2. 从零开始构建前向传播2.1 计算隐藏层节点值2.2 应用激活函数2.3 计算输出层值2.4 计算损失值2.4.1 在连续变…

C++鼠标轨迹算法(鼠标轨迹模拟真人移动)

一.简介 鼠标轨迹算法是一种模拟人类鼠标操作的程序,它能够模拟出自然而真实的鼠标移动路径。 鼠标轨迹算法的底层实现采用C/C语言,原因在于C/C提供了高性能的执行能力和直接访问操作系统底层资源的能力。 鼠标轨迹算法具有以下优势: 模拟…

Java从入门到工作2 - IDEA

2.1、项目启动 从git获取到项目代码后,用idea打开。 安装依赖完成Marven/JDK等配置检查数据库配置启动相关服务 安装依赖 如果个别依赖从私服下载不了,可以去maven官网下载补充。 如果run时提示程序包xx不存在,在项目目录右键Marven->Re…

【AI知识】过拟合、欠拟合和正则化

一句话总结: 过拟合和欠拟合是机器学习中的两个相对的概念,正则化是用于解决过拟合的方法。 1. 欠拟合: 指模型在训练数据上表现不佳,不能充分捕捉数据的潜在规律,导致在训练集和测试集上的误差都很高。欠拟合意味着模…

汽车升级到底应不应该设置“可取消“功能

最近,汽车OTA(Over-the-Air)升级频频成为车主讨论的热点。有些车主反映,一些升级增加了实用功能,而另一些却让体验变得复杂甚至带来不便。于是,大家不禁发问:汽车升级功能究竟应不应该允许“可取…

优选算法——分治(快排)

1. 颜色分类 题目链接:75. 颜色分类 - 力扣(LeetCode) 题目展示: 题目分析:本题其实就要将数组最终分成3块儿,这也是后面快排的优化思路,具体大家来看下图。 这里我们上来先定义了3个指针&…

[Maven]下载安装、配置与简介

很多框架的下载使用的流程和思路是差不多的,这里以maven做详细介绍。 下载安装与配置变量 下载 首先,我们要使用maven,必须先下载它的相关文件。想要下载,我们可以直接搜索maven。找到它的官网。这里不绕弯子,直接给出…

Maven 安装配置(详细教程)

文章目录 一、Maven 简介二、下载 Maven三、配置 Maven3.1 配置环境变量3.2 Maven 配置3.3 IDEA 配置 四、结语 一、Maven 简介 Maven 是一个基于项目对象模型(POM)的项目管理和自动化构建工具。它主要服务于 Java 平台,但也支持其他编程语言…

【AI知识】人工智能、机器学习、深度学习的概念与联系

下图来自博客 机器学习和深度学习概念入门 ,图中可明显看到人工智能、机器学习、深度学习三个概念的包含关系,下面简单介绍一下这三个概念已经它们之间的联系。 1. 人工智能(Artificial Intelligence,AI) 概念&#x…

BUUCTF Pwn bjdctf_2020_babystack2 题解

1.下载 checksec 64位 拖入IDA64 定位到main函数 以及后门函数 发现read需要读取输入——nbytes的数字来决定长度 同时nbytes是size_t类型 也就是无符号整型的 所以想到整数溢出漏洞 将nbytes设置为-1就会回绕,变成超大整数 从而实现栈溢出漏洞 exp&#xff1a…

微服务-01【续】

1.OpenFeign 上篇文章我们利用Nacos实现了服务的治理,利用利用RestTemplate实现了服务的远程调用。但是远程调用的代码太复杂了: 而且这种调用方式,与原本的本地方法调用差异太大,编程时的体验也不统一,一会儿远程调用…

中电金信携手中远海科,共启贸易金融数智新篇章

在数智化转型成为驱动经济社会高质量发展的新引擎背景下,“数智方案”栏目聚焦金融等国计民生重点行业场景,依托中电金信“源启筑基咨询引领应用重构”的产品及服务体系,输出市场洞察和行业解决方案、应用案例,旨在全面推动行业IT…

【前端】React快速构建登陆注册前后端全栈

近期更新完毕,建议关注、收藏! 目录 快速入门 快速入门 前提:安装npm #npm install react react-dom conda install nodejs npm install create-react-app cd my-app#切换到项目文件夹 npm install npm i web-vitals --save-dev #如果上述…

JS中的原型链与继承

文章目录 原型链的类比原型链对像与函数拥有的原型属性不同原型链的产生对象的constructor属性继承 原型链的类比 JS中原型链,本质上就是对象之间的关系,通过protoype和[[Prototype]]属性建立起来的连接。这种链条是动态的,可以随时变更。 …

Ubuntu22.04搭建FTP服务器保姆级教程

在网络环境中,文件传输是一项至关重要的任务。FTP(文件传输协议)是一种基于客户端/服务器模式的协议,广泛用于在互联网上传输文件。Ubuntu作为一款流行的Linux发行版,因其稳定性和易用性而广受开发者和系统管理员的喜爱…

基于Kubesphere实现微服务的CI/CD——部署微服务项目(三)

目录 一、kubesphere安装 1、安装本地持久存储 1.1、default-storage-class.yaml 1.2、 openebs-operator.yaml 1.3、安装 Default StorageClass 2、安装kubesphere 2.1、安装Helm 2.2、安装kubesphere 二、配置kubesphere 1、安装插件 2、创建devops项目 3、配置…

jenkins harbor安装

Harbor是一个企业级Docker镜像仓库‌。 文章目录 1. 什么是Docker私有仓库2. Docker有哪些私有仓库3. Harbor简介4. Harbor安装 1. 什么是Docker私有仓库 Docker私有仓库是用于存储和管理Docker镜像的私有存储库。Docker默认会有一个公共的仓库Docker Hub,而与Dock…

open cv学习之图片矫正

一,实验原理 图像矫正的原理是透视变换 图像畸变主要有两类:径向畸变和切向畸变。径向畸变通常会导致图像的四个角向外或向内弯曲;切向畸变则是由于相机与图像平面不完全平行引起的。而OpenCV 提供了一个相机标定的工具,能够自动…

【再谈设计模式】组合模式~层次构建的多面手

一、引言 在软件开发的世界里,我们经常面临着处理对象之间复杂关系的挑战。如何有效地表示对象的部分 - 整体层次结构,并且能够以一种统一的方式操作这些对象,是一个值得探讨的问题。组合模式(Composite Pattern)为我们…

关于Git分支合并,跨仓库合并方式

关于Git合并代码的方式说明 文章目录 关于Git合并代码的方式说明前情提要开始合并方式一:git merge方式二:git cherry-pick方式三:git checkout Git跨仓库合并的准备事项前提拉取源仓库代码 前情提要 同仓库不同分支代码的合并可直接往下看文…