精心修炼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…...
IDEA运行Tomcat出现乱码问题解决汇总
最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…...
高频面试之3Zookeeper
高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个?3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制(过半机制࿰…...
Cloudflare 从 Nginx 到 Pingora:性能、效率与安全的全面升级
在互联网的快速发展中,高性能、高效率和高安全性的网络服务成为了各大互联网基础设施提供商的核心追求。Cloudflare 作为全球领先的互联网安全和基础设施公司,近期做出了一个重大技术决策:弃用长期使用的 Nginx,转而采用其内部开发…...
【学习笔记】深入理解Java虚拟机学习笔记——第4章 虚拟机性能监控,故障处理工具
第2章 虚拟机性能监控,故障处理工具 4.1 概述 略 4.2 基础故障处理工具 4.2.1 jps:虚拟机进程状况工具 命令:jps [options] [hostid] 功能:本地虚拟机进程显示进程ID(与ps相同),可同时显示主类&#x…...
【开发技术】.Net使用FFmpeg视频特定帧上绘制内容
目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法,当前调用一个医疗行业的AI识别算法后返回…...
鸿蒙DevEco Studio HarmonyOS 5跑酷小游戏实现指南
1. 项目概述 本跑酷小游戏基于鸿蒙HarmonyOS 5开发,使用DevEco Studio作为开发工具,采用Java语言实现,包含角色控制、障碍物生成和分数计算系统。 2. 项目结构 /src/main/java/com/example/runner/├── MainAbilitySlice.java // 主界…...
算法笔记2
1.字符串拼接最好用StringBuilder,不用String 2.创建List<>类型的数组并创建内存 List arr[] new ArrayList[26]; Arrays.setAll(arr, i -> new ArrayList<>()); 3.去掉首尾空格...
MySQL账号权限管理指南:安全创建账户与精细授权技巧
在MySQL数据库管理中,合理创建用户账号并分配精确权限是保障数据安全的核心环节。直接使用root账号进行所有操作不仅危险且难以审计操作行为。今天我们来全面解析MySQL账号创建与权限分配的专业方法。 一、为何需要创建独立账号? 最小权限原则…...
云原生玩法三问:构建自定义开发环境
云原生玩法三问:构建自定义开发环境 引言 临时运维一个古董项目,无文档,无环境,无交接人,俗称三无。 运行设备的环境老,本地环境版本高,ssh不过去。正好最近对 腾讯出品的云原生 cnb 感兴趣&…...
AI+无人机如何守护濒危物种?YOLOv8实现95%精准识别
【导读】 野生动物监测在理解和保护生态系统中发挥着至关重要的作用。然而,传统的野生动物观察方法往往耗时耗力、成本高昂且范围有限。无人机的出现为野生动物监测提供了有前景的替代方案,能够实现大范围覆盖并远程采集数据。尽管具备这些优势…...
