Java synchronized(详细)
synchronized
一,介绍
在Java中,synchronized
关键字用于解决多线程并发访问共享资源时可能出现的线程安全问题。当多个线程同时访问共享资源时,如果没有合适的同步机制,可能会导致以下问题:
-
竞态条件(Race Condition):多个线程在没有适当同步的情况下同时访问共享资源,由于执行顺序不确定,可能导致结果的不确定性或错误。
-
数据不一致性:由于并发访问导致数据的部分修改或读取,可能导致数据的不一致性。
-
内存可见性:由于线程之间的工作内存与主内存的不同步,一个线程对共享变量的修改可能对其他线程不可见,导致读取到旧的值。
synchronized
关键字可以解决上述问题,它提供了两种主要的同步机制:
-
互斥访问:
synchronized
确保在同一时刻只有一个线程可以进入被synchronized
修饰的代码块或方法,从而避免了多个线程同时修改共享资源的情况,解决了竞态条件问题。 -
内存可见性:
synchronized
不仅保证了互斥访问,还保证了同步代码块中共享变量的修改对其他线程可见,即确保了线程之间的内存可见性。
通过使用synchronized
,开发人员可以有效地确保多线程环境下共享资源的安全访问,避免了潜在的线程安全问题。然而,需要注意的是,过度使用synchronized
可能会导致性能下降,因此在使用时应谨慎权衡。
Java中的synchronized关键字用于实现线程同步,可以修饰方法或代码块。
1. 修饰方法:
当一个方法被synchronized修饰时,只有获得该方法的锁的线程才能执行该方法。其他线程需要等待锁的释放才能执行该方法。
我们将创建多个线程来同时增加和减少计数器的值。
下面是修改后的代码:
public class Counter {private int count = 0;// 同步方法,使用 synchronized 修饰public synchronized void increment() {count++;}// 同步方法,使用 synchronized 修饰public synchronized void decrement() {count--;}// 非同步方法public int getCount() {return count;}
}public class Main {public static void main(String[] args) {Counter counter = new Counter();// 创建并启动增加计数器值的线程Thread incrementThread = new Thread(() -> {for (int i = 0; i < 1000; i++) {counter.increment();}});// 创建并启动减少计数器值的线程Thread decrementThread = new Thread(() -> {for (int i = 0; i < 1000; i++) {counter.decrement();}});// 启动线程incrementThread.start();decrementThread.start();// 等待两个线程执行完毕try {incrementThread.join();decrementThread.join();} catch (InterruptedException e) {e.printStackTrace();}// 输出计数器的值System.out.println("Final count: " + counter.getCount());}
}
在这个示例中,我们创建了两个线程:一个增加计数器值的线程incrementThread
和一个减少计数器值的线程decrementThread
。这两个线程会同时运行,并且通过调用Counter
类中的同步方法来修改计数器的值。
最后,我们等待这两个线程执行完毕,并输出最终的计数器值。由于我们使用了synchronized
修饰方法来确保对计数器的安全访问,所以最终输出的计数器值应该是预期的结果。
3. 修饰代码块:
当某个对象被synchronized修饰时,任何线程在执行该对象中被synchronized修饰的代码块时,必须先获得该对象的锁。其他线程需要等待锁的释放才能执行同步代码块。Java中的每个对象都有一个内置锁,当一个对象被synchronized修饰时,它的内置锁就起作用了。只有获得该锁的线程才能访问被synchronized修饰的代码段。使用synchronized可以保证多个线程对共享数据的访问顺序,避免了竞态条件和数据不一致的问题。注意:synchronized关键字只能保证同一对象内部的线程同步,不能保证多个对象的同步。如果需要多个对象之间的同步,可以考虑使用Lock接口的实现类。
在Java中,synchronized
关键字用于实现线程同步,可以修饰代码块、方法以及静态方法。当synchronized
修饰一个代码块时,它会锁定一个对象,确保同时只有一个线程可以进入被修饰的代码块,从而保证了线程安全。
语法格式为:
synchronized (对象) {// 需要同步的代码块
}
在这个语法中,括号内的对象是一个锁对象,每个Java对象都可以作为锁对象。当一个线程进入synchronized
代码块时,它会尝试获取锁对象,如果锁对象被其他线程占用,则当前线程会被阻塞,直到获取到锁对象后才能继续执行。当线程执行完synchronized
代码块后会释放锁对象,其他线程就可以获取锁对象继续执行synchronized
代码块。
下面是一个简单的示例:
public class Example {private static final Object lock = new Object();public void method() {synchronized (lock) {// 同步代码块// 在这里访问共享资源}}
}
在这个示例中,lock
对象被用作锁对象,只有获取了这个锁对象的线程才能进入synchronized
代码块。
二,锁升级
按照锁的升级顺序,可以将锁状态和过渡描述为以下几个步骤:
1.无锁状态(Unlocked):
初始时,资源处于无锁状态,没有线程正在使用它。
偏向锁(Biased Locking):当一个线程第一次进入同步代码块时,会尝试获取偏向锁。如果成功,该线程会标记为拥有偏向锁,并记录下自己的线程 ID。这样,在未发生竞争的情况下,该线程后续访问同步代码块时可以快速获取锁,避免了重量级锁的开销。
2.轻量级锁(Lightweight Locking):
当两个或多个线程开始竞争同一个锁时,偏向锁会升级为轻量级锁。此时,JVM 会使用 CAS(Compare and Swap)操作来尝试获取锁。如果成功,当前线程会获得轻量级锁,并继续执行临界区代码;如果失败,表示有其他线程持有锁,需要进行锁的膨胀。
3.自旋锁(Spin Locking):
在轻量级锁的基础上,为了避免线程阻塞和降低线程切换的开销,如果获取轻量级锁失败,当前线程会选择进行自旋,即忙等待一段时间。它会尝试多次使用 CAS 操作来获取锁,期望其他线程能够快速释放锁。如果在自旋期间成功获取了锁,线程可以继续执行临界区代码;否则,会进一步升级为重量级锁。
4.重量级锁(Heavyweight Locking):
当自旋锁无法获取到锁时或自旋次数达到一定阈值,轻量级锁会膨胀为重量级锁。此时,JVM 使用操作系统的互斥量(Mutex)来实现锁,并将当前线程阻塞,直到获取到锁为止。其他线程需要等待持有锁的线程释放锁后才能获取锁并执行临界区代码。
这是锁状态的一个常见升级顺序,它描述了锁的不同阶段和相应的过渡。但需要注意的是,在具体实现中,JVM 和不同的 Java 版本可能会有一些优化和变化,因此实际的锁升级过程可能略有不同。
锁会升级的主要原因是为了解决并发环境下的线程竞争和保证数据的一致性。当多个线程同时竞争同一个锁时,如果使用低级别的锁(如偏向锁或轻量级锁),可能会导致一些问题,例如:
竞争激烈:如果多个线程频繁地竞争同一个锁,轻量级锁的 CAS 操作可能会失败,导致自旋失败,增加了线程切换的开销。
锁撤销:偏向锁只能保证在没有竞争的情况下加锁的效率,一旦有其他线程竞争锁,就需要将偏向锁撤销,转而升级为更高级别的锁。
锁膨胀:对于长时间持有锁的线程,自旋可能会浪费大量的 CPU 时间,不仅影响性能,还会导致其他线程无法及时获取锁。此时,将轻量级锁膨胀为重量级锁,可以将持有锁的线程阻塞,避免自旋带来的性能损耗。
因此,为了提高并发的效率和线程安全性,锁会根据实际情况进行升级。锁的升级过程就是将低级别的锁转换为高级别的锁,以应对竞争激烈、长时间持有锁的情况,从而保证线程的顺序执行和数据的一致性。锁升级的原则是在减少线程切换开销、提高吞吐量和保证线程安全之间找到一个平衡点,以最优的方式处理并发情况。
三,什么是CAS
CAS(Compare and Swap)是一种并发算法,用于实现多线程环境下的原子操作。它是一种乐观锁策略,通过比较内存中的值与期望值是否相等来判断数据是否被修改,从而进行原子操作。
CAS 操作通常涉及三个参数:内存地址(或变量),期望值和新值。CAS 操作会先读取内存中的值与期望值进行比较,如果相等,则将新值写入内存中,并返回操作成功;如果不相等,则说明其他线程已经修改了内存的值,CAS 操作失败,需要重新尝试。
CAS 操作是原子性的,因为它在执行期间不会被中断或打断。它可以提供非阻塞的原子性操作,避免了使用锁造成的线程阻塞和上下文切换的开销。相比传统的加锁操作,CAS 操作通常具有更高的并发性能。
CAS 在并发编程中有广泛的应用,例如乐观锁、无锁数据结构和线程安全的计数器等。但需要注意的是,CAS 操作虽然能够解决一些并发问题,但在高并发环境下可能存在ABA问题(即在修改期间,数据经过了一系列变化又回到了原始状态),需要额外的手段来解决。
import java.util.concurrent.atomic.AtomicInteger;public class CASExample {private static AtomicInteger counter = new AtomicInteger(0);public static void main(String[] args) {// 模拟多个线程同时对计数器进行累加操作Thread thread1 = new Thread(new CounterRunnable());Thread thread2 = new Thread(new CounterRunnable());thread1.start();thread2.start();// 等待两个线程执行完毕try {thread1.join();thread2.join();} catch (InterruptedException e) {e.printStackTrace();}// 输出最终的计数器值System.out.println("Final Counter Value: " + counter.get());}static class CounterRunnable implements Runnable {@Overridepublic void run() {// 对计数器进行1000次累加操作for (int i = 0; i < 1000; i++) {// 使用CAS操作进行原子性累加while (true) {int currentValue = counter.get();int newValue = currentValue + 1;if (counter.compareAndSet(currentValue, newValue)) {break; // CAS操作成功,退出循环}// CAS操作失败,继续尝试}}}}
}
相关文章:
Java synchronized(详细)
synchronized 一,介绍 在Java中,synchronized关键字用于解决多线程并发访问共享资源时可能出现的线程安全问题。当多个线程同时访问共享资源时,如果没有合适的同步机制,可能会导致以下问题: 竞态条件(…...

算法设计与分析实验报告python实现(排序算法、三壶谜题、交替放置的碟子、带锁的门)
一、 实验目的 1.加深学生对算法设计方法的基本思想、基本步骤、基本方法的理解与掌握; 2.提高学生利用课堂所学知识解决实际问题的能力; 3.提高学生综合应用所学知识解决实际问题的能力。 二、实验任务 1、排序算法…...
实训问题总结——ajax用get可以成功调用controller方法,用POST就出404错误
因为传输密码时必须用POST。 还有用GET传输参数,说有非法字符,想试试POST是否可以解决。 404错误的三个大致原因,1:找不到对的请求路径,2:请求方式错误,3、请求参数错误。 后来可以调用了。但…...

1、认识MySQL存储引擎吗?
目录 1、MySQL存储引擎有哪些? 2、默认的存储引擎是哪个? 3、InnoDB和MyISAM有什么区别吗? 3.1、关于事务 3.2、关于行级锁 3.3、关于外键支持 3.4、关于是否支持MVCC 3.5、关于数据安全恢复 3.6、关于索引 3.7、关于性能 4、如何…...
微信小程序媒体查询
在微信小程序中,media媒体查询不支持screen关键字,因为小程序页面是再webview中渲染的,而不是在浏览器中渲染的。 在设置样式时,可以使用 wxss 文件中的 media 规则来根据屏幕宽度或高度设置不同的样式。 device-width:设备屏幕…...

前端(动态雪景背景+动态蝴蝶)
1.CSS样式 <style>html, body, a, div, span, table, tr, td, strong, ul, ol, li, h1, h2, h3, p, input {font-weight: inherit;font-size: inherit;list-style: none;border-spacing: 0;border: 0;border-collapse: collapse;text-decoration: none;padding: 0;margi…...

软考-系统集成项目管理中级-新一代信息技术
本章历年考题分值统计 本章重点常考知识点汇总清单(掌握部分可直接理解记忆) 本章历年考题及答案解析 32、2019 年上半年第 23 题 云计算通过网络提供可动态伸缩的廉价计算能力,(23)不属于云计算的特点。 A.虚拟化 B.高可扩展性 C.按需服务 D.优化本地存储 【参考…...

【卷积神经网络进展】
打基础日常记录 CNN基础知识1. 感知机2. DNN 深度神经网络(全连接神经网络)DNN 与感知机的区别DNN特点,全连接神经网络DNN前向传播和反向传播 3. CNN结构【提取特征分类】4. CNN应用于文本 CNN基础知识 1. 感知机 单层感知机就是一个二分类…...
yarn的安装和使用
windows mac 环境 yarn的安装和使用 yarn安装 npm install -g yarnyarn设置代理 yarn config set registry https://registry.npm.taobao.org -gyarn官方源 yarn config set registry https://registry.yarnpkg.comyarn使用 // 查看板本 yarn --version// 安装指定包 yarn…...

Golang | Leetcode Golang题解之第10题正则表达式匹配
题目: 题解: func isMatch(s string, p string) bool {m, n : len(s), len(p)matches : func(i, j int) bool {if i 0 {return false}if p[j-1] . {return true}return s[i-1] p[j-1]}f : make([][]bool, m 1)for i : 0; i < len(f); i {f[i] m…...

【Leetcode】top 100 图论
基础知识补充 1.图分为有向图和无向图,有权图和无权图; 2.图的表示方法:邻接矩阵适合表示稠密图,邻接表适合表示稀疏图; 邻接矩阵: 邻接表: 基础操作补充 1.邻接矩阵: class GraphAd…...
【沈阳航空航天大学】 <C++ 类与对象计分作业>
C类与对象 1. 设计用类完成计算两点距离2. 设计向量类3. 求n!4. 出租车收费类的设计与实现5. 定义并实现一个复数类6. 线性表类的设计与实现7. 数组求和8. 数组求最大值 1. 设计用类完成计算两点距离 【问题描述】设计二维点类Point,包括私有成员:横坐标…...
Vue3 自定义指令Custom Directives
简介 在vue中重用代码的方式有:组件、组合式函数。组件是主要的构建模块,而组合式函数更偏重于有状态的逻辑。 指令系统给我们提供了例如:v-model、v-bind,vue系统允许我们自定义指令,自定义指令也是一种重用代码的方式…...

蓝桥杯 【日期统计】【01串的熵】
日期统计 第一遍写的时候会错了题目的意思,我以为是一定要八个整数连在一起构成正确日期,后面发现逻辑明明没有问题但是答案怎么都是错的才发现理解错了题目的意思,题目的意思是按下标顺序组成,意思就是可以不连续,我…...
CSP201409T5拼图
题意:给出一个 n m nm nm的方格图,现在要用如下L型的占3个的积木拼到这个图中,总共有多少种拼法使图满。 #include<bits/stdc.h> using namespace std; long long n,m,k1,Now; int Mod1000000007; struct Matrix {long long a[129][129];Matrix(…...

mongoDB 优化(2)索引
执行计划 语法:1 db.collection_xxx_t.find({"param":"xxxxxxx"}).explain(executionStats) 感觉这篇文章写得很好,可以参考 MongoDB——索引(单索引,复合索引,索引创建、使用)_mongo…...

【2024系统架构设计】案例分析- 5 Web应用
目录 一 基础知识 二 真题 一 基础知识 1 Web应用技术分类 大型网站系统架构的演化:高性能、高可用、可维护、应变、安全。 从架构来看:MVC,MVP,MVVM,REST,Webservice,微服务。...

布隆过滤器详解及java实现
什么是布隆过滤器? 布隆过滤器(Bloom Filter)是一种数据结构,用于判断一个元素是否属于一个集合。它的特点是高效地判断一个元素是否可能存在于集合中,但是存在一定的误判率。 布隆过滤器的基本原理是使用一个位数组…...

CloudCompare 点云工具
CloudCompare 点云工具 1. CloudCompare简介1.1 CloudCompare下载 2. CloudCompare安装 1. CloudCompare简介 CloudCompare 是一款开源的三维点云处理软件,它提供了一系列功能来处理、查看和分析三维点云数据。这个软件可以用于许多不同的应用领域,包括…...

Linux 著名的sudo、su是什么?怎么用?
一、su 什么是su? su命令(简称是:substitute 或者 switch user )用于切换到另一个用户,没有指定用户名,则默认情况下将以root用户登录。 为了向后兼容,su默认不改变当前目录,只设…...
React 第五十五节 Router 中 useAsyncError的使用详解
前言 useAsyncError 是 React Router v6.4 引入的一个钩子,用于处理异步操作(如数据加载)中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误:捕获在 loader 或 action 中发生的异步错误替…...
论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)
HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...
Java 语言特性(面试系列1)
一、面向对象编程 1. 封装(Encapsulation) 定义:将数据(属性)和操作数据的方法绑定在一起,通过访问控制符(private、protected、public)隐藏内部实现细节。示例: public …...

在WSL2的Ubuntu镜像中安装Docker
Docker官网链接: https://docs.docker.com/engine/install/ubuntu/ 1、运行以下命令卸载所有冲突的软件包: for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done2、设置Docker…...

pikachu靶场通关笔记22-1 SQL注入05-1-insert注入(报错法)
目录 一、SQL注入 二、insert注入 三、报错型注入 四、updatexml函数 五、源码审计 六、insert渗透实战 1、渗透准备 2、获取数据库名database 3、获取表名table 4、获取列名column 5、获取字段 本系列为通过《pikachu靶场通关笔记》的SQL注入关卡(共10关࿰…...
学习一下用鸿蒙DevEco Studio HarmonyOS5实现百度地图
在鸿蒙(HarmonyOS5)中集成百度地图,可以通过以下步骤和技术方案实现。结合鸿蒙的分布式能力和百度地图的API,可以构建跨设备的定位、导航和地图展示功能。 1. 鸿蒙环境准备 开发工具:下载安装 De…...

【无标题】湖北理元理律师事务所:债务优化中的生活保障与法律平衡之道
文/法律实务观察组 在债务重组领域,专业机构的核心价值不仅在于减轻债务数字,更在于帮助债务人在履行义务的同时维持基本生活尊严。湖北理元理律师事务所的服务实践表明,合法债务优化需同步实现三重平衡: 法律刚性(债…...

macOS 终端智能代理检测
🧠 终端智能代理检测:自动判断是否需要设置代理访问 GitHub 在开发中,使用 GitHub 是非常常见的需求。但有时候我们会发现某些命令失败、插件无法更新,例如: fatal: unable to access https://github.com/ohmyzsh/oh…...
【HarmonyOS 5】鸿蒙中Stage模型与FA模型详解
一、前言 在HarmonyOS 5的应用开发模型中,featureAbility是旧版FA模型(Feature Ability)的用法,Stage模型已采用全新的应用架构,推荐使用组件化的上下文获取方式,而非依赖featureAbility。 FA大概是API7之…...
在RK3588上搭建ROS1环境:创建节点与数据可视化实战指南
在RK3588上搭建ROS1环境:创建节点与数据可视化实战指南 背景介绍完整操作步骤1. 创建Docker容器环境2. 验证GUI显示功能3. 安装ROS Noetic4. 配置环境变量5. 创建ROS节点(小球运动模拟)6. 配置RVIZ默认视图7. 创建启动脚本8. 运行可视化系统效果展示与交互技术解析ROS节点通…...