深入理解Happens-Before原则:以实例解析并发编程的基石

在最近的一次面试中面试官问到了Happens-Before原则,作此篇回顾下知识点。

在并发编程中,为了保证程序的正确性和可预测性,我们需要理解并遵循一系列内存访问规则。Happens-Before原则定义了线程间可见性和顺序性的保证。所有此篇文章将通过实例详细介绍Happens-Before原则。

在这里插入图片描述

Happens-Before原则概述

Happens-Before原则是Java内存模型(JMM)中定义的一种偏序关系,用于确定两个操作之间的相对顺序。

如果操作A happens-before 操作B,那么操作A的结果对操作B是可见的,且操作A的执行顺序在操作B之前。这就意味着,当线程B读取到线程A写入的值时,可以确保线程A的写入操作已经发生。

Happens-Before原则的实例解析

单一线程内的操作

在一个线程内,按照程序顺序执行的操作自然满足Happens-Before原则。这是因为单个线程内的操作是顺序执行的,没有并发访问的问题。

举个栗子:

	int a = 1; // 操作A  

	int b = a; // 操作B

在这个例子中,操作A(给变量a赋值为1)happens-before操作B(读取变量a的值并赋给变量b)。所以,操作B读取到的b的值一定是1。

锁的释放与获取

当一个线程释放锁时,它之前对共享变量的修改对其他线程是可见的;当一个线程获取锁时,它可以读取到之前释放锁线程对共享变量的修改。这里,锁的释放操作happens-before锁的获取操作。

举个栗子:

	Object lock = new Object();  

	int sharedVariable = 0;  

	  

	// 线程A  

	synchronized(lock) {  

	    sharedVariable = 1; // 操作A  

	} // 释放锁  

	  

	// 线程B  

	synchronized(lock) {  

	    int temp = sharedVariable; // 操作B  

	} // 获取锁

对于上面的栗子,线程A在释放锁之前将sharedVariable赋值为1(操作A)。由于锁的释放操作happens-before锁的获取操作,线程B在获取锁后读取到的sharedVariable的值一定是1。

volatile变量的写与读

对volatile变量的写操作happens-before后续对该变量的读操作。这就意味着,当一个线程写入一个volatile变量时,其他线程可以立即看到这个修改。

举个栗子:

	volatile boolean flag = false;  

	  

	// 线程A  

	flag = true; // 操作A  

	  

	// 线程B  

	if (flag) { // 操作B  

	    // ...  

	}

上面的代码中,线程A将volatile变量flag设置为true(操作A)。因为volatile变量的写操作happens-before读操作,线程B在读取flag时,一定能够看到其值为true

线程启动与终止

线程的启动(start)操作happens-before此线程内的任意操作。线程的所有操作都happens-before其他线程检测到该线程已经终止(通过Thread.join()方法或Thread.isAlive()的返回值等方法)。

举个例子:

	Thread thread = new Thread(() -> {  

	    // 线程内操作  

	    System.out.println("xiaowei haoshuai!");  

	});  

	thread.start(); // 操作A  

	thread.join(); // 操作B

上面的代码中,线程启动操作(操作A)happens-before线程内的打印操作,而线程内的打印操作又happens-before线程终止检测操作(操作B)。因此,主线程在调用thread.join()方法时,可以确保子线程已经执行了打印操作。

Happens-Before原则小结

Happens-Before原则是并发编程中的基石,它定义了线程间操作顺序和可见性的保证。

我们理解并遵循这一原则,就可以编写出正确且可预测的并发程序。本篇文章到此结束,希望我们开发者们在编写代码时都牢记住这一原则哦!

在这里插入图片描述

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

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

相关文章

针对pycharm打开新项目需要重新下载tensorflow的问题解决

目录 一、前提 二、原因 三、解决办法 一、前提 下载包之前,已经打开了,某个项目。 比如:我先打开了下面这个项目: 然后在terminal使用pip命令下载: 如果是这种情况,你下载的这个包一般都只能用在这一个…

【学习笔记】java项目—苍穹外卖day04

文章目录 1. 新增套餐1.1 需求分析和设计1.2 代码实现1.2.1 DishController1.2.2 DishService1.2.3 DishServiceImpl1.2.4 DishMapper1.2.5 DishMapper.xml1.2.6 SetmealController1.2.7 SetmealService1.2.8 SetmealServiceImpl1.2.9 SetmealMapper1.2.10 SetmealMapper.xml1.…

【Docker】搭建强大的Nginx可视化配置工具 - nginxWebUI

【Docker】搭建强大的Nginx可视化配置工具 - nginxWebUI 前言 本教程基于绿联的NAS设备DX4600 Pro的docker功能进行搭建。 简介 NginxWebUI是一个基于Java的,专门用来管理Nginx的图形界面工具。它是开源的,使用相对简单且功能全面。 使用NginxWebUI…

Android裁剪图片为波浪形或者曲线形的ImageView

如果需要做一个自定义的波浪效果的进度条,裁剪图片,对ImageView的图片进行裁剪,比如下面2张图,如何实现? 先看下面的效果,看到其实只需要对第一张高亮的图片进行处理即可,灰色状态的作为背景图。…

link 样式表是否会阻塞页面内容的展示?取决于浏览器,edge 和 chrome 会,但 firefox 不会。

经过实测: 在 head 中 link 一个 1M 大小的样式表。设置网络下载时间大概为 10 秒。 edge 和 chrome 只有在下载完样式表后,页面上才会出现内容。而 firefox 可以直接先显示内容,然后等待样式表下载完成后再应用样式。 DOMContentLoaded 事…

我如何学会在学术界培养人际关系,并变得更加友善

我是一名初级教授,压力很大,工作到筋疲力尽,但在工作和家庭中仍然感到不足。因此,当我的入门编程课程的三名学生在学期结束时来到我的办公室,对他们的成绩感到担忧时,我觉得我没有时间处理他们的抱怨。我觉…

Vulnhub:MY FILE SERVER: 1

目录 信息收集 1、arp 2、nmap 3、whatweb WEB web信息收集 dirmap FTP匿名登录 enum4linux smbclient showmount FTP登录 ssh-kegen ssh登录 提权 系统信息收集 脏牛提权 get root 信息收集 1、arp ┌──(root㉿ru)-[~/kali/vulnhub] └─# arp-scan -l I…

2024UI自动化面试题汇总【建议收藏】

1.你是如何搭建ui自动化框架的? 在搭建ui自动化框架,使用的是po设计模式,也就是把每一个页面所需要 操作的元素和步骤都封装成一个页面类中。然后使用seleniumunittest搭建 四层框架实现数据、脚本、业务逻辑分离(关键字驱动&…

【微服务】配置Nacos管理SpringBoot配置文件(附解压包)

📝个人主页:哈__ 期待您的关注 一、什么是Nacos Nacos可以帮助我们配置和管理微服务,是阿里的一个开源产品,是针对微服务架构中的服务发现、配置管理、服务治理的综合型解决方案。Nacos可以用来实现配置中心和服务注册中心。 …

【3月30日信息差】2G 50/年,4G 618/3年 云服务器全网对比 游戏服务器活动 我的世界 幻兽帕鲁 雾锁王国通用

本文纯原创,侵权必究 【云服务器推荐】价格对比!阿里云 京东云 腾讯云 选购指南视频截图 《最新对比表》已更新在文章头部—腾讯云文档,文章具有时效性,请以腾讯文档为准! 【腾讯文档实时更新】2024年-幻兽帕鲁服务器…

Python数据结构实验 图实验(一)

一、实验目的 1.熟悉图的相关概念,包括有向图、无向图、完全图、子图、路径、简单路径、路径长度、回路等定义; 2.掌握图的各种存储结构,主要包括邻接矩阵和邻接表的相关算法设计; 3.掌握图的…

node.js 入门案例 安装教程

前言 Node.js是一个基于Chrome JavaScript 运行时建立的一个平台。 Node.js是一个事件驱动I/O服务端JavaScript环境,基于Google的V8引擎,V8引擎执行Javascript的速度非常快,性能非常好。 可以让JavaScript在服务器端运行。它具有轻量级、高…

网络安全--内网篇

一、环境 一个简单的域环境,3台机器即可,一个server2012,win7,,win10 二、开始初始的认识内网 在我们日常渗透中,我们进入企业去进行渗透的时候都是处于一个域的环境下,简单来说域一类网络服务而在服务器…

HarmonyOS实战开发-如何实现一个自定义抽奖圆形转盘

介绍 本篇Codelab是基于画布组件、显式动画,实现的一个自定义抽奖圆形转盘。包含如下功能: 通过画布组件Canvas,画出抽奖圆形转盘。通过显式动画启动抽奖功能。通过自定义弹窗弹出抽中的奖品。 相关概念 Stack组件:堆叠容器&am…

JavaScript基础语法–详谈

JavaScript的编写方式 这里小编写一个简单代码,展示JavaScript三种编写方式 HTML代码行内(可以理解为内联样式) a.第一种方式 一个123的网址,通过点击实现浏览器显示welcome字样提升(与浏览器进行交互)…

【AI模型-机器学习工具部署】远程服务器配置Jupyter notebook或jupyter lab服务

随着AI人工智能的崛起,机器学习、深度学习、模型训练等技术也慢慢泛化,java开发有idea,web开发有vscode,那么AI开发神器肯定离不开jupyter lab(基础版jupyter notebook) Jupyter notebook部署 1. 安装jupy…

基于Python实现多功能翻译助手(上)

创建一个支持多种语言翻译并且允许通过文件拖拽来输入文本的Python窗口应用程序是一个相对复杂的任务,涉及到多个库和组件。以下是一个简化的指南,展示如何使用Python的Tkinter库创建GUI窗口,结合Googletrans库进行翻译,以及使用P…

第十四章 MySQL

一、MySQL 1.1 MySql 体系结构 MySQL 架构总共四层,在上图中以虚线作为划分。 1. 最上层的服务并不是 MySQL 独有的,大多数给予网络的客户端/服务器的工具或者服务都有类似的架构。比如:连接处理、授权认证、安全等。 2. 第二层的架构包括…

Python连接MySQL

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 一、整体思路二、连接流程三、表结构及代码实现 一、整体思路 二、连接流程 三、表结构及代码实现 代码块如下: import pymysqlcon pymysql.connect(h…

websocket 局域网 webrtc 一对一 视频通话的实例

基本介绍 使用websocket来 WebRTC 建立连接时的 数据的传递和交换。 WebRTC 建立连接时,通常需要按照以下顺序执行一些步骤: 1.创建本地 PeerConnection 对象:使用 RTCPeerConnection 构造函数创建本地的 PeerConnection 对象,该…