Java面试之Happens-Before原则

此篇接上一篇的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。



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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

AB plc设备数据 转 opc ua项目案例

目录 1 案例说明 2 VFBOX网关工作原理 3 准备工作 4 网关采集AB PLC数据 5 启动OPC UA协议转发采集的数据 6 案例总结 1 案例说明 设置网关采集AB PLC数据把采集的数据转成opc ua协议转发给其他系统。 2 VFBOX网关工作原理 VFBOX网关是协议转换网关,是把一种…

ASP.NET|日常开发中连接Sqlite数据库详解

ASP.NET|日常开发中连接Sqlite数据库详解 前言一、安装和引用相关库1.1 安装 SQLite 驱动1.2 引用命名空间 二、配置连接字符串2.1 连接字符串的基本格式 三、建立数据库连接3.1 创建连接对象并打开连接 四、执行数据库操作4.1 创建表(以简单的用户表为例…

Redis篇-6--原理篇5--单线程模型

1、概述 Redis 采用单线程模型来处理客户端请求,这意味着在任意时刻只有一个命令被执行。这种设计简化了 Redis 的实现,并确保了高并发环境下的数据一致性。尽管 Redis 是单线程的,但它通过高效的内存管理和网络 I/O 操作,仍然能…

Spring Boot + Spring AI快速体验

Spring AI快速体验 1 什么是Spring AI主要功能 2 快速开始2.1 版本说明2.2 配置文件2.3 pom依赖2.3.1 spring maven仓库2.3.2 核心依赖 2.4 定义ChatClient2.5 启动类2.6 测试 3 参考链接 1 什么是Spring AI Spring AI是Spring的一个子项目,是Spring专门面向于AI的…

【Unity】【VR开发】摩托车游戏开发笔记1-摩托车手把旋转时轴位移问题

【背景】 做VR摩托车游戏时,需要给摩托车加仿真控制,其中就有抓握龙头旋转时转弯的实现。 实现分两部分,一个是视觉上的动画实现,一个是摩托车实际的位移控制实现。先实现动画效果,也就是抓握把手能够让车头左右旋转。这里先简单一点,实现左手单手让车头旋转。 【设计】…

uniapp -- 实现页面滚动触底加载数据

效果 首选,是在pages.json配置开启下拉刷新 {"path": "pages/my/document/officialDocument","style": {"navigationStyle":</

丹摩|丹摩助力selenium实现大麦网抢票

丹摩&#xff5c;丹摩助力selenium实现大麦网抢票 声明&#xff1a;非广告&#xff0c;为用户体验 1.引言 在人工智能飞速发展的今天&#xff0c;丹摩智算平台&#xff08;DAMODEL&#xff09;以其卓越的AI算力服务脱颖而出&#xff0c;为开发者提供了一个简化AI开发流程的强…

Android系统(android app和系统架构)

文章目录 AndroidAndroid Apps四大组件 Android系统Platform API之下&#xff1a;一个微笑内核adb(Android Debug Bridge) Android包管理机制Android的Intent机制参考 Android LinuxFrameworkJVM 在Linux/Java上做了个二次开发&#xff1f;并不完全是&#xff1a;Android定义…

小程序开发中的插件生态与应用-上

更多精彩内容都在公zhong号&#xff1a;小白的大数据之旅 在小程序的开发过程中&#xff0c;插件作为扩展功能、提升效率的重要工具&#xff0c;扮演着不可或缺的角色。它们不仅能够帮助开发者快速集成复杂的功能模块&#xff0c;还能优化开发流程&#xff0c;缩短项目周期。 …

An error happened while trying to locate the file on the Hub and we cannot f

An error happened while trying to locate the file on the Hub and we cannot find the requested files in the local cache. Please check your connection and try again or make sure your Internet connection is on. 关于上述comfy ui使用control net预处理器的报错问…

Java 实现给pdf文件指定位置盖章功能

Java 实现给pdf文件指定位置盖章功能 开发中遇到一个需求, 需要给用户上传的的pdf文件, 指定位置上盖公章的功能, 经过调研和对比, 最终确定实现思路. 这里是使用pdf文件中的关键字进行章子的定位, 之所以这样考虑是因为如果直接写死坐标的话, 可能会出现因pdf大小, 缩放, 盖章…

Vmware的网络适配器的NAT模式和桥接模式有何区别?如何给Uubunt系统添加桥接网卡?

Vmware的网络适配器的NAT模式和桥接模式有何区别&#xff1f; 如何给Uubunt系统添加桥接网卡? 步骤如下&#xff1a;

主机连不上CentOS7虚拟机Redis

CentOS7中的Redis连不上主机 是否ping通 先尝试主机是否能Ping通虚拟机 虚拟机中查看ens33对应的地址&#xff0c;使用ifconfig 再在主机上尝试Ping&#xff0c;如果无法Ping通&#xff0c;先排除是否是虚拟机NAT或者桥接模式配置的问题 redis.conf配置 我是按照黑马的教…

vue element 切换 select 下拉框的 单选多选报错

今天根据项目需求&#xff0c;需要对下拉框进行&#xff0c;单双选判断&#xff0c;当多选切换成多选&#xff0c;没有问题但是单选切换成多选报错如下 页面是要求 选择in或者notin时候 多选 经过好长时间摸索&#xff0c;解决了&#xff0c;最后使用select的失去焦点事件解决的…

VBA高级应用30例应用在Excel中的ListObject对象:向表中添加注释

《VBA高级应用30例》&#xff08;版权10178985&#xff09;&#xff0c;是我推出的第十套教程&#xff0c;教程是专门针对高级学员在学习VBA过程中提高路途上的案例展开&#xff0c;这套教程案例与理论结合&#xff0c;紧贴“实战”&#xff0c;并做“战术总结”&#xff0c;以…

BA和CS算法中的Levy飞行策略

Levy飞行策略通过模拟自然界中动物的长距离迁徙行为&#xff0c;指导粒子进行更大范围的搜索&#xff0c;有助于算法快速找到全局最优解。它是一种具有独特优势的随机行为策略&#xff0c;模拟随机游走或搜索过程中的步长和方向&#xff0c;其步长的概率分布为重尾分布&#xf…

JavaEE多线程案例之阻塞队列

上文我们了解了多线程案例中的单例模式&#xff0c;此文我们来探讨多线程案例之阻塞队列吧 1. 阻塞队列是什么&#xff1f; 阻塞队列是⼀种特殊的队列.也遵守"先进先出"的原则. 阻塞队列是⼀种线程安全的数据结构,并且具有以下特性: 当队列满的时候,继续⼊队列就会…

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

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

centos部署SkyWalking以及在springcloud项目中搭配loki使用

文章目录 场景SkyWalking介绍部署部署Storage [单机版Elasticsearch]部署SkyWalking OAP [下载地址](https://skywalking.apache.org/downloads/#SkyWalkingAPM)部署SkyWalking Java Agent springCloud 使用举例追踪ID写入loki 场景 SkyWalking是应用性能监控平台&#xff0c;可…

FastAPI vs Flask 选择最适合您的 Python Web 框架

文章目录 1. 简介2. 安装和设置3. 路由和视图4. 自动文档生成5. 数据验证和序列化6. 性能和异步支持结论 在 Python Web 开发领域&#xff0c;FastAPI 和 Flask 是两个备受欢迎的选择。它们都提供了强大的工具和功能&#xff0c;但是在某些方面有所不同。本文将比较 FastAPI…