Synchronized同步锁

news/2024/5/18 23:14:12/文章来源:https://blog.csdn.net/qq_49841284/article/details/134001026

synchronized

一,介绍

Java中的synchronized关键字用于实现线程同步,可以修饰方法或代码块。

1. 修饰方法:当一个方法被synchronized修饰时,只有获得该方法的锁的线程才能执行该方法。其他线程需要等待锁的释放才能执行该方法。

2. 修饰代码块:当某个对象被synchronized修饰时,任何线程在执行该对象中被synchronized修饰的代码块时,必须先获得该对象的锁。其他线程需要等待锁的释放才能执行同步代码块。Java中的每个对象都有一个内置锁,当一个对象被synchronized修饰时,它的内置锁就起作用了。只有获得该锁的线程才能访问被synchronized修饰的代码段。使用synchronized可以保证多个线程对共享数据的访问顺序,避免了竞态条件和数据不一致的问题。注意:synchronized关键字只能保证同一对象内部的线程同步,不能保证多个对象的同步。如果需要多个对象之间的同步,可以考虑使用Lock接口的实现类。

二,锁升级

按照锁的升级顺序,可以将锁状态和过渡描述为以下几个步骤:

  1. 无锁状态(Unlocked):初始时,资源处于无锁状态,没有线程正在使用它。
  2. 偏向锁(Biased Locking):当一个线程第一次进入同步代码块时,会尝试获取偏向锁。如果成功,该线程会标记为拥有偏向锁,并记录下自己的线程 ID。这样,在未发生竞争的情况下,该线程后续访问同步代码块时可以快速获取锁,避免了重量级锁的开销。
  3. 轻量级锁(Lightweight Locking):当两个或多个线程开始竞争同一个锁时,偏向锁会升级为轻量级锁。此时,JVM 会使用 CAS(Compare and Swap)操作来尝试获取锁。如果成功,当前线程会获得轻量级锁,并继续执行临界区代码;如果失败,表示有其他线程持有锁,需要进行锁的膨胀。
  4. 自旋锁(Spin Locking):在轻量级锁的基础上,为了避免线程阻塞和降低线程切换的开销,如果获取轻量级锁失败,当前线程会选择进行自旋,即忙等待一段时间。它会尝试多次使用 CAS 操作来获取锁,期望其他线程能够快速释放锁。如果在自旋期间成功获取了锁,线程可以继续执行临界区代码;否则,会进一步升级为重量级锁。
  5. 重量级锁(Heavyweight Locking):当自旋锁无法获取到锁时或自旋次数达到一定阈值,轻量级锁会膨胀为重量级锁。此时,JVM 使用操作系统的互斥量(Mutex)来实现锁,并将当前线程阻塞,直到获取到锁为止。其他线程需要等待持有锁的线程释放锁后才能获取锁并执行临界区代码。

这是锁状态的一个常见升级顺序,它描述了锁的不同阶段和相应的过渡。但需要注意的是,在具体实现中,JVM 和不同的 Java 版本可能会有一些优化和变化,因此实际的锁升级过程可能略有不同。

锁会升级的主要原因是为了解决并发环境下的线程竞争和保证数据的一致性。当多个线程同时竞争同一个锁时,如果使用低级别的锁(如偏向锁或轻量级锁),可能会导致一些问题,例如:

  1. 竞争激烈:如果多个线程频繁地竞争同一个锁,轻量级锁的 CAS 操作可能会失败,导致自旋失败,增加了线程切换的开销。
  2. 锁撤销:偏向锁只能保证在没有竞争的情况下加锁的效率,一旦有其他线程竞争锁,就需要将偏向锁撤销,转而升级为更高级别的锁。
  3. 锁膨胀:对于长时间持有锁的线程,自旋可能会浪费大量的 CPU 时间,不仅影响性能,还会导致其他线程无法及时获取锁。此时,将轻量级锁膨胀为重量级锁,可以将持有锁的线程阻塞,避免自旋带来的性能损耗。

因此,为了提高并发的效率和线程安全性,锁会根据实际情况进行升级。锁的升级过程就是将低级别的锁转换为高级别的锁,以应对竞争激烈、长时间持有锁的情况,从而保证线程的顺序执行和数据的一致性。锁升级的原则是在减少线程切换开销、提高吞吐量和保证线程安全之间找到一个平衡点,以最优的方式处理并发情况。

三,什么是CAS

CAS(Compare and Swap)是一种并发算法,用于实现多线程环境下的原子操作。它是一种乐观锁策略,通过比较内存中的值与期望值是否相等来判断数据是否被修改,从而进行原子操作。

CAS 操作通常涉及三个参数:内存地址(或变量),期望值和新值。CAS 操作会先读取内存中的值与期望值进行比较,如果相等,则将新值写入内存中,并返回操作成功;如果不相等,则说明其他线程已经修改了内存的值,CAS 操作失败,需要重新尝试。

CAS 操作是原子性的,因为它在执行期间不会被中断或打断。它可以提供非阻塞的原子性操作,避免了使用锁造成的线程阻塞和上下文切换的开销。相比传统的加锁操作,CAS 操作通常具有更高的并发性能。

CAS 在并发编程中有广泛的应用,例如乐观锁、无锁数据结构和线程安全的计数器等。但需要注意的是,CAS 操作虽然能够解决一些并发问题,但在高并发环境下可能存在ABA问题(即在修改期间,数据经过了一系列变化又回到了原始状态),需要额外的手段来解决。

四,synchronized示例代码

以下是使用 Java 中的 `synchronized` 关键字实现同步的示例代码:

1. 同步方法示例:
 

public class SynchronizedExample {private int count = 0;public synchronized void increment() {count++;}public synchronized void decrement() {count--;}
}

在上面的示例中,`increment()` 和 `decrement()` 方法都被声明为 `synchronized`,这意味着一次只能有一个线程访问这些方法。当一个线程正在执行其中一个方法时,其他线程必须等待。

2. 同步代码块示例:

public class SynchronizedExample {private int count = 0;private Object lock = new Object();public void increment() {synchronized (lock) {count++;}}public void decrement() {synchronized (lock) {count--;}}
}

在上面的示例中,我们使用一个对象 `lock` 作为锁来创建同步代码块。在 `increment()` 和 `decrement()` 方法中,只有一个线程可以同时进入同步代码块,并且执行完同步代码块后会释放锁。

需要注意的是,在使用 `synchronized` 时,应该选择合适的对象作为锁,以避免不必要的竞争。通常,我们可以使用类的某个成员变量或者专门为同步目的创建一个 `Object` 对象作为锁。

以上示例代码演示了如何在 Java 中使用 `synchronized` 关键字进行同步。然而,Java 还提供了其他同步机制,如 `ReentrantLock`、`Semaphore` 等,可以根据具体的需求选择合适的同步方式。

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

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

相关文章

数据集特征预处理

1、什么是特征预处理 1.1、什么是特征预处理 scikit-learn的解释 provides several common utility functions and transformer classes to change raw feature vectors into a representation that is more suitable for the downstream estimators. 翻译过来:通…

2023年中国汽车覆盖件模具竞争格局、市场规模及行业需求前景[图]

汽车覆盖件模具是汽车车身生产的重要工艺装备,其设计和制造时间约占汽车开发周期的 2/3,是汽车换型的重要制约因素之一。汽车覆盖件模具具有尺寸大、工作型面复杂、技术标准高等特点,属于技术密集型产品。汽车覆盖件模具按以其冲压的汽车覆盖…

找不到concrt140.dll无法继续执行此代码的解决方法总结,快速解决dll问题的5种方法

最近,我在使用电脑的过程中遇到了一个问题,即“找不到concrt140.dll无法继续执行此代码”。通过查阅资料和自己的实践,我了解到concrt140.dll是Microsoft Visual C 2015 Redistributable中的一个动态链接库文件。它提供了一些用于支持多线程编…

不同类型的RFID标签及其应用场景浅析

RFID技术是一种利用无线电信号进行数据传输和识别的技术,根据标签的不同特点和应用场景,RFID标签可以分为多种类型,下面将详细介绍不同类型的RFID标签及其应用场景。 一、有无电源电池 1.1 有源RFID标签 有源RFID标签内置电池,…

5年经验之谈 —— 手把手教你接口性能测试之JMeter性能测试篇!

本文是我们《手把手教你接口性能测试》系列文章中的完结篇,介绍如何使用JMeter工具进行接口测试和并发测试。 一、Jmeter 简介 Jmeter是由Apache公司开发的一个纯Java开源项目,即可以用于做接口测试也可以用于做性能测试,具备高移植性和扩展…

针对遗留系统采取的不同演化策略

1. 改造策略 高水平、高价值区,即遗留系统的技术含量较高,本身还有极大的生命力。系统具有较高的业务价值,基本上能够满足企业业务运作和决策支持的需要。这种系统可能建成的时间还很短,对这种遗留系统的演化策略为改造。改造包括…

考过PMP之后,要不要继续学CSPM?

在7年前拿下了PMP证书,但又在今年报名了CSPM中级的学习,身边很多人都疑问,为什么还要继续花钱考一个新出的证书?是不是闲的没事干?下面跟大家说下我的想法,仅作参考。 1)了解项目管理行业的新动…

如何制作自己的数字人

如何制作自己的数字人呢?不用担心平台的使用授权,也不用担心哪一天自己自媒体被号被无故封杀,那么SadTalker将是你的首选,他是完全开源的数字人软件,现已达到Apache2的授权,完全自由的开源软件。作者自己试…

二进制明文字符串加密:还原与反还原

背景 上一篇文章中介绍了xorstr的原理和最小化验证概念的代码,这篇文章来看下这种已经被广泛应用于各恶意样本以及安全组件中的技术如何还原,如果还没看上篇建议先看下了解其实现后再看本篇文章 xorstr的现状 随着相关技术的应用越来越广,…

基于RuoYi-Flowable-Plus的若依ruoyi-nbcio支持多实例自定义条件的流程流转

更多ruoyi-nbcio功能请看演示系统 gitee源代码地址 前后端代码: https://gitee.com/nbacheng/ruoyi-nbcio 演示地址:RuoYi-Nbcio后台管理系统 1、前端代码,主要修改下面这个文件,如下: 说明几点: 1.1 …

Python Opencv实践 - 车辆统计(2)检测线绘制,车辆数量计数和显示

针对我所使用的视频,对上一节的代码进行了修改,增加了更多参数。 Python Opencv实践 - 车辆统计(1)读取视频,移除背景,做预处理_亦枫Leonlew的博客-CSDN博客示例中的图像的腐蚀、膨胀和闭运算等需要根据具…

微机原理与接口技术-第七章输入输出接口

文章目录 I/O接口概述I/O接口的典型结构基本功能 I/O端口的编址独立编址统一编址 输入输出指令I/O寻址方式I/O数据传输量I/O保护 16位DOS应用程序DOS平台的源程序框架DOS功能调用 无条件传送和查询传送无条件传送三态缓冲器锁存器接口电路 查询传送查询输入端口查询输出端口 中…

err -110 while initial SD card failed enmmm否系解决方案

1.情况表述 之前把 sd卡从小容量换成了大容量 且运行正常 过了一两个月 发现启动失败 报错:mmc0: error -110 whilst initialising SD card 给出报错图片 2.相关解决方案 给出链接 讲的很有道理,但是 我在bash中没有找到对应内核的驱动文件 SD卡…

【JavaScript】JavaScript基础详解(文末送书)

👉博__主👈:米码收割机 👉技__能👈:C/Python语言 👉公众号👈:测试开发自动化【获取源码商业合作】 👉荣__誉👈:阿里云博客专家博主、5…

Java 线程池调度周期性任务“异常“探究

背景 在做性能监控需求的过程中,会存在很多监控任务需要定时执行。比如在卡顿监控的实现中,我们需要每50ms 执行一次主线程调用栈的任务,此时由于任务本身可能存在一些耗时,可能需要对任务下次调度的时间做一些调整,避…

有没有人声和背景音乐分离的神器?

做视频剪辑,二次创作的朋友,需要去除视频中的背景音乐,保留人声;或者去除人声,保留背景音乐。随着用户需求的增多,科技的发展,让我们能通过智能的人声分离软件来实现,下面就来看看如…

XPS的锂电池表征技巧-科学指南针

XPS作为一种表面表征手段,这是它一个很大的限制,同时也是它一个很大的优势,正所谓“其术专则其艺必精”。限于笔者专业背景,此次主要讲述XPS在锂离子电池中的应用。 而由于XPS测试是一种表面分析手段,故其在锂离子电池…

Qt中QFile、QByteArray QDataStream和QTextStream区别及示例

在Qt中,QFile、QByteArray、QDataStream和QTextStream是常用的文件和数据处理类。 主要功能和区别 QFile: QFile是用于读写文本和二进制文件以及资源的I/O设备。可以单独使用QFile,或者更方便地与QTextStream或QDataStream一起使用。 通常在…

最新2023版完美可用的聚合支付系统源码,全开源无后门,适合二开

最新2023版完美可用的聚合易支付系统源码,全开源无后门,真正安全可用。 更新日志: 1.新增微信公众号消息提醒功能 2.重构转账付款功能,支持通过插件扩展 3.商户后台新增代付功能 4.后台新增付款记录列表 5.支付宝插件新增预…

嵌入式养成计划-46----QT--简易版网络聊天室实现--QT如何连接数据库

一百一十九、简易版网络聊天室实现 119.1 QT实现连接TCP协议 119.1.1 基于TCP的通信流程 119.1.2 QT中实现服务器过程 使用QTcpServer实例化一个服务器对象设置监听状态,通过listen()函数,可以监听特定的主机,也可以监听所有客户端&#x…