精心修炼Java并发编程(JUC)-volatile与synchronized关键字
volatile
volatile 是 JVM 提供的 最轻量级的同步机制,中文意思是不稳定的,易变的,用 volatile
修饰变量是为了保证变量在多线程中的可见性,它表达的含义是:告诉编译器,对这个变量的读写,需要基于主内存保证多CPU的缓存一致性。
volatile 变量的两个特性:解决可见性和有序性
1、解决可见性
保证变量对所有线程的可见性:当一条线程修改了 volatile 变量的值,新值对于其他线程来说是可以立即得知的。而普通变量不能做到这一点
线程写 volatile 变量的过程:
- 改变线程工作内存中 volatile 变量副本的值
- 将改变后的副本的值立即从工作内存刷新到主内存
线程读 volatile 变量的过程:
- 从主内存中读取 volatile 变量的最新值到线程的工作内存中
- 从工作内存中读取 volatile 变量的副本
注意:
1、volatile并不能保证并发操作的原子性,即不保证线程安全
2、volatile修饰引用类型,它只能保证引用本身的可见性,不能保证所引用对象内部属性的可见性
2、解决有序性
禁止进行指令重排序,具体一点解释,禁止重排序的规则如下:
- 写
volatile
变量时,可以确保volatile
写之前的操作不会被编译器重排序到volatile
写之后。 - 读
volatile
变量时,可以确保volatile
读之后的操作不会被编译器重排序到volatile
读之前。
synchronized
如果某一个资源被多个线程共享,为了避免因为资源抢占导致资源数据错乱,我们需要对线程进行同步,那么synchronized就是实现线程同步的关键字
synchronized的作用是保证在同一时刻, 被修饰的代码块或方法只会有一个线程执行,以达到保证并发安全的效果。
其用法如下:
从语法上讲,Synchronized可以把任何一个非null对象作为"锁",在HotSpot JVM实现中,锁有个专门的名字:对象监视器(Object Monitor)。
// (1)修饰静态方法
public synchronized static void helloStatic(){System.out.println("hello world static");
}// (2)修饰成员函数
public synchronized void hello(){System.out.println("hello world");
}// (3)直接定义代码块
public void test(){SynchronizedTest test = new SynchronizedTest(); synchronized (test){System.out.println("hello world");}
}
synchronized其底层说白了就是锁,所以呢,我们先从锁讲起
我们知道发生原子性的根源是CPU在执行完任意指令后都有可能发生线程切换。如果能够禁用线程切换的话那这个问题也就迎刃而解了。操作系统做线程切换是依赖 CPU 中断的,所以禁止 CPU 发生中断就能够禁止线程切换。
1、加锁和解锁操作在哪里体现的?
synchronized 的加锁和解锁是隐式实现的,可以查看字节码
2、synchronized 的锁对象是什么,也就是说锁定的是哪个对象?
- 如果修饰的是代码块,锁对象是我们自己指定的,指定哪个对象就锁定哪个对象。
- 如果修饰的是非静态方法,锁定的是当前实例对象
this
。 - 如果修饰的是静态方法,锁定的是当前类的 Class 对象。
Linux内核提供的锁机制
1、Mutex(互斥量):pthread_mutex_t,通过对该结构的操作,来判断资源是否可以访问,Mutex属于sleep-waiting类型的锁,例如在多核机器上有两个线程A,B,如果此时锁被A持有,那么B就会被阻塞,在等待队列中等待。
2、Spin lock(自旋锁):pthread_spinlock_t,属于busy-waiting类型的锁,它不会引起调用者睡眠等待,如果获取不到锁则进入忙等待,它会不停的尝试去获取锁,俗称自旋,获取锁的性能相对较高,但是费CPU,所以自旋锁不应该被长时间的持有。
3、 Condition Variable(条件变量):pthread_cond_t,条件变量是利用线程间共享的全局变量,进行同步的一种机制
4、Read/Write Lock(读写锁):pthread_rwlock_t,读写锁是用来解决读多写少问题的,读操作可以共享,写操作是排他的。
5、semaphore:sem_t,信号量(semaphore)机制,也可用于互斥锁的实现
synchronized底层
public static void synClass() {Object obj = new Object();synchronized (obj) {}
}
我们看看这段代码的字节码文件
0 new #2 <java/lang/Object>3 dup4 invokespecial #1 <java/lang/Object.<init> : ()V>7 astore_18 aload_19 dup
10 astore_2
11 monitorenter
12 aload_2
13 monitorexit
14 goto 22 (+8)
17 astore_3
18 aload_2
19 monitorexit
20 aload_3
21 athrow
22 return
其中跟synchronized关键字相关的就是这样的字节码
monitorenter
........
monitorexit
monitorenter主要是获取监视器锁,monitorexit主要是释放监视器锁,所以我们的synchronized就是去获取这个监控锁对象,他会在我们的对象头中(markword)
markword图示如下:
加锁过程
前面我们看到了synchronized在字节码层面是对应monitorenter
合monitorexit
,而真正实现互斥的锁其实依赖操作系统底层的Mutex Lock
来实现,首先要明确一点,这个锁是一个重量级的锁
整体锁升级的过程大致可以分为两条路径,如下:
1、偏向锁未启动,加锁默认加轻量级锁
轻量级锁:线程在自己的线程栈生成Lock Record
,使用CAS的方式将markword设置为指向自己线程LOCK Record
的指针,设置成功者得锁。竞争会让锁膨胀为重量级锁。
2、偏向锁启动
偏向锁,偏向的是第一个来获取锁的线程。所谓偏向锁,指的是获取锁的线程在markword中写自己的线程ID的过程,偏向锁升级为轻量级锁时首先要撤销偏向锁,如何设置轻量级锁。
偏向锁默认是打开的,但是启动有一个时延,默认4s,之所以要延迟,是因为JVM虚拟机自己有一些默认的启动线程,里面有好多sync代码,这些代码启动时就肯定会有竞争,如果直接使用偏向锁,就会造成偏向锁不断的进行锁撤销和锁升级的操作,效率较低。
我们平时使用synchronized注意点总结如下:
-
降低锁的等级
能用对象级别的,尽量别用类锁,能用实例变量的不要用静态变量
-
减少锁的时间 不需要同步执行的代码,能不放在同步块里面执行就不要放在同步快内,可以让锁尽快释放
-
减少锁的粒度 共享资源数决定锁的数量。有一组资源定义一把锁,而不是多组资源共用一把锁,增加并行度,从而降低锁竞争,典型如分段锁
-
减少加减锁的次数 假如有一个循环,循环内的操作需要加锁,我们应该把锁放到循环外面,否则每次进出循环,都要加锁
-
读写锁 业务细分,读操作加读锁,可以并发读,写操作使用写锁
-
善用volatile
volatile的控制比synchronized更轻量化,在某些变量上不涉及多步打包操作和原子性问题,可以加以运用。
如ConcurrentHashMap的get操作,使用的volatile而不是加锁
相关文章:
精心修炼Java并发编程(JUC)-volatile与synchronized关键字
volatile volatile 是 JVM 提供的 最轻量级的同步机制,中文意思是不稳定的,易变的,用 volatile 修饰变量是为了保证变量在多线程中的可见性,它表达的含义是:告诉编译器,对这个变量的读写,需要基…...
【ROS2】ROS2 与 ROS1 编码方式对比(Python实现)
目录 一、初始化和关闭节点二、发布者三、订阅者四、服务端五、客户端六、参数管理七、日志记录八、生命周期管理 ROS2 在 Python 编程中引入了一些新的概念和 API,这些变化使得代码更加模块化和易于维护。特别是 rclpy 库提供了更丰富的功能和更好的错误处理机制&a…...
ElasticSearch的下载和基本使用(通过apifox)
1.概述 一个开源的高扩展的分布式全文检索引擎,近乎实时的存储,检索数据 2.安装路径 Elasticsearch 7.8.0 | Elastic 安装后启动elasticsearch-7.8.0\bin里的elasticsearch.bat文件, 启动后就可以访问本地的es库http://localhost:9200/ …...
城市轨道交通运营控制指挥中心设计方案
为某城市轨道交通运营控制指挥中心(OCC)的设计提供方案时,我们需要考虑到多个方面的需求,包括系统架构、设备选择、功能实现、数据流与监控、通信管理等。以下是一个综合性的设计方案,涉及系统硬件和软件的选择、布局规划、安全性等方面,以确保指挥中心的高效运作、实时监…...
多目标优化算法:多目标河马优化算法(MOHOA)求解ZDT1、ZDT2、ZDT3、ZDT4、ZDT6,提供完整MATLAB代码
一、河马优化算法 河马优化算法(Hippopotamus optimization algorithm,HO)由Amiri等人于2024年提出的一种模拟自然界中河马觅食行为的新型群体智能优化算法。该算法由Mohammad Hussein Amiri等人于2024年2月发表在Nature旗下子刊《Scientifi…...
线程与进程的个人理解
进程(Process): 一个程序在执行时,操作系统为其分配的资源(如内存、CPU 时间等)构成了一个进程。每个进程都有自己的独立的地址空间、堆栈和局部变量,它们之间不共享内存(除非通过特…...
vscode的项目给gitlab上传
目录 一.创建gitlab帐号 二.在gitlab创建项目仓库 三.Windows电脑安装Git 四.vscode项目git上传 一.创建gitlab帐号 二.在gitlab创建项目仓库 图来自:Git-Gitlab中如何创建项目、创建Repository、以及如何删除项目_gitlab新建项目-CSDN博客) 三.Windows电脑安…...
企业微信定位打卡
废话少说:定位修改软件链接奉上 一、定位打卡原理 GPS定位:企业微信可以利用手机的GPS功能进行定位,这是一种基于卫星的定位技术,能够提供相对精确的位置信息,通常精确度在20米以内。这种方式耗电较大,且在…...
libaom 源码分析:码率控制介绍
码率控制 命令行码率控制选项:可以看到码率控制包括丢帧、resize、超分、码控模式、目标码率、目标上限下限(类似 x264、x265 中的 VBV)、码控偏置、GOP 码率等。Rate Control Options:--drop-frame=<arg> Temporal resampling threshold (buf %)--resize-mo…...
RK3568平台开发系列讲解(DMA篇)DMA engine使用
🚀返回专栏总目录 文章目录 一、申请DMA channel二、配置DMA channel的参数三、获取传输描述(tx descriptor)四、启动传输沉淀、分享、成长,让自己和他人都能有所收获!😄 📢DMA子系统下有一个帮助测试的测试驱动(drivers/dma/dmatest.c), 从这个测试驱动入手我们了解…...
C++中的函数对象
C 中函数对象的定义和特点 定义:函数对象(Function Object)也叫仿函数(Functor),是一个类,这个类重载了函数调用运算符()。当创建这个类的对象后,可以像使用函数一样使用这个对象&am…...
Linux指标之平均负载(The Average load of Linux Metrics)
💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:Linux运维老纪的首页…...
盛最多水的容器
本节将数组与坐标轴共同组成一个容器,通过改变容器的两个端点使容器装的水最多,容器两个端点不断移动可以通过左右指针算法解决. 问题描述: 给定两个非负整数k1,k2...km每个数代表坐标中的一个点(i,ki).在坐标内绘制m条垂线,垂直线i的两个端点分别为(i,k1)和(i,0)找出其中的两…...
光伏功率预测!Transformer-LSTM、Transformer、CNN-LSTM、LSTM、CNN五模型时序预测
目录 预测效果基本介绍程序设计参考资料 预测效果 基本介绍 Transformer-LSTM、Transformer、CNN-LSTM、LSTM、CNN五模型多变量时序光伏功率预测 (Matlab2023b 多输入单输出) 1.程序已经调试好,替换数据集后,仅运行一个main即可运行,数据格式…...
java全栈day10--后端Web基础(基础知识)
引言:只要能通过浏览器访问的网站全是B/S架构,其中最常用的服务器就是Tomcat 在浏览器与服务器交互的时候采用的协议是HTTP协议 一、Tomcat服务器 1.1介绍 官网地址:Apache Tomcat - Welcome! 1.2基本使用(网上有安装教程,建议…...
使用爬虫时,如何确保数据的准确性?
在数字化时代,数据的准确性对于决策和分析至关重要。本文将探讨如何在使用Python爬虫时确保数据的准确性,并提供代码示例。 1. 数据清洗 数据清洗是确保数据准确性的首要步骤。在爬取数据后,需要对数据进行清洗,去除重复、无效和…...
Burp入门(4)-扫描功能介绍
声明:学习视频来自b站up主 泷羽sec,如涉及侵权马上删除文章 感谢泷羽sec 团队的教学 视频地址:burp功能介绍(1)_哔哩哔哩_bilibili 本文介绍burp的主动扫描和被动扫描功能。 一、主动扫描 工作原理: 主动…...
Tourtally:颠覆传统的AI智能旅行规划革命
# Tourtally:颠覆传统的AI智能旅行规划革命 在快速变化的旅行科技世界里,一个划时代的平台正在重新定义我们探索世界的方式。让我们一起认识 Tourtally,这个由人工智能驱动的旅行规划助手,正在彻底改变旅行体验。 ## 旅行规划的…...
chrome允许http网站打开摄像头和麦克风
第一步 chrome://flags/#unsafely-treat-insecure-origin-as-secure 第二步 填入网址,点击启用 第三步 重启 Chrome:设置完成后,点击页面底部的 “Relaunch” 按钮,重新启动 Chrome 浏览器,使更改生效。...
视觉经典神经网络与复现:深入解析与实践指南
目录 引言 经典视觉神经网络模型详解 1. LeNet-5:卷积神经网络的先驱 LeNet-5的关键特点: 2. AlexNet:深度学习的突破 AlexNet的关键特点: 3. VGGNet:深度与简洁的平衡 VGGNet的关键特点: 4. ResNe…...
ByConity ELT 测试体验
在实际业务中,用户会基于不同的产品分别构建实时数仓和离线数仓。其中,实时数仓强调数据能够快速入库,且在入库的第一时间就可以进行分析,低时延的返回分析结果。而离线数仓强调复杂任务能够稳定的执行完,需要更好的内…...
对象键值对内容映射
对象映射: 数据字段的英文名映射为更易理解的中文标签进行展示。即数据字段英文名 -> 中文描述。 作用: 提高代码的可读性。支持数据字段与展示内容的解耦,方便修改展示语言或样式,而无需改动数据源。 映射特点:…...
《生成式 AI》课程 第7講:大型語言模型修練史 — 第二階段: 名師指點,發揮潛力 (兼談對 ChatGPT 做逆向工程與 LLaMA 時代的開始)
资料来自李宏毅老师《生成式 AI》课程,如有侵权请通知下线 Introduction to Generative AI 2024 Springhttps://speech.ee.ntu.edu.tw/~hylee/genai/2024-spring.php 摘要 这一系列的作业是为 2024 年春季的《生成式 AI》课程设计的,共包含十个作业。…...
学习C#中的反射
在C#编程中,反射(Reflection)是一项强大且灵活的技术,它允许程序在运行时动态地获取类型信息、创建对象实例、调用方法、访问字段和属性等。这种机制极大地增强了程序的动态性和可扩展性,使得开发者能够在编译时未知的…...
学习使用jquery实现在指定div前面增加内容
学习使用jquery实现在指定div前面增加内容 设计思路代码示例 设计思路 选择要添加内容的指定元素: 使用jQuery选择器来选择你希望在其前添加内容的元素。例如,如果你有一个 元素,其ID为qipa250,你可以使用$(‘#qipa250’)来选择…...
react项目初始化配置步骤
1.npx create-react-app 项目名称 vue项目同理 2.去编辑器市场安装所需插件,例如ESlint以及Prettier-Code formatter formatiing-toggle 3.在项目中安装 ESLint 和 Prettier 及相关插件: 3.1: npm install --save-dev eslint prettier 3.2…...
vue使用百度富文本编辑器
1、安装 npm add vue-ueditor-wrap 或者 pnpm add vue-ueditor-wrap 进行安装 2、下载UEditor 官网:ueditor:rich text 富文本编辑器 - GitCode 整理好的:vue-ueditor: 百度编辑器JSP版 因为官方的我没用来,所以我自己找的另外的包 …...
异常处理(6)自定义异常
异常处理(6)自定义异常类 1、自定义异常要求: (1)要继承一个异常类型 自定义一个编译时异常类型:自定义类继承java.lang.Exception。 自定义一个运行时异常类型:自定义类继承java.lang.Runtim…...
微软正在测试 Windows 11 对第三方密钥的支持
微软目前正在测试 WebAuthn API 更新,该更新增加了对使用第三方密钥提供商进行 Windows 11 无密码身份验证的支持。 密钥使用生物特征认证,例如指纹和面部识别,提供比传统密码更安全、更方便的替代方案,从而显著降低数据泄露风险…...
时间的礼物:如何珍视每一刻
《时间的礼物:如何珍视每一刻》 夫时间者,宇宙之精髓,生命之经纬,悄无声息而流转不息,如织锦之细线,串联古今,贯穿万物。 人生短暂,犹如白驹过隙,倏忽而逝,…...
房屋租赁网站开发意义/模板建站的网站
1 auto_ptr auto_ptr模板定义了类似指针的对象,是一种智能指针,当auto_ptr对象过期时,其析构函数将使用delete来释放内存。 void test1() {int* ip new int(10); //动态内存未释放return; }void test2() {auto_ptr<int> ip(new int(…...
科技有限公司 网站制作/赣州seo顾问
发现一个很好用的图片压缩的拓展。将图片压缩成以设定的宽度,高度以图片自己的高度比例缩放,以及压缩图片的数据大小达到低于设定的值。 使用到的地方还是不少,比如分享图文到朋友圈时就有限制图片不大于32K。 #import <UIKit/UIKit.h&g…...
wordpress命令执行时间/百度官网地址
Item 2:Prefer readonly to const 这个Item主要讲作为常量的两种形式(readonly和const)的区别。 const是编译时常量,指在编译时直接把这个静态常量直接替换成相应的数值readonly是运行时常量,指编译时任然是静态常量,在…...
什么是网站设计/google优化推广
2019独角兽企业重金招聘Python工程师标准>>> CentOS7查看CPU个数 查看逻辑cpu个数:cat /proc/cpuinfo | grep "processor" | wc -l 查看物理cpu个数:cat /proc/cpuinfo | grep "physical id" | sort | uniq | wc -l 查看…...
wordpress批量添加分类/汕头seo优化公司
if($_GET[t]1) { print_r($ret); } 在页面的url之后添加一个参数&t1 方法2:file_put_contents("/tmp/XXX", print_r($XXX,1)); 添加代码完之后进行语法校验 php -l t.php 转载于:https://www.cnblogs.com/pandajingjing/p/5625813.html...
织梦网站/游戏推广话术
你应该给对手一些东西,让他们感到好过,这对你有好处,特别是在此举并不需要你投入太多的时候。 不要给自己制造不必要的麻烦冲突会引发强烈的情感,其中就包括愤怒。这些强烈的情感会干扰我们进行战略性思考的能力,让我们…...