Synchronized同步锁

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.rhkb.cn/news/168380.html

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

相关文章

Python+requests+pytest+excel+allure 接口自动化测试实战

定义: Unittest是Python标准库中自带的单元测试框架,Unittest有时候也被称为PyUnit,就像JUnit是Java语言的标准单元测试框架一样,Unittest则是Python语言的标准单元测试框架。 Pytest是Python的另一个第三方单元测试库。它的目的…

Linux C语言开发-D2vi编辑器使用

三种模式基础 命令行模式、插入模式和底行模式 :! [命令]:可在命令行模式下执行命令 :w test1.cc可备份当前编辑的文件 :r head.h可为当前文件引入头文件 u:撤销 命令行进入插入模式: i:从当前光标位置之前开始插入 …

Mac 开机提示Google LLC 注册 无法登录进入系统

Google LLC 会在电脑启动时提示如下弹窗,并要求登录谷歌账户进行验证 此时很明显没有用来进行验证的账号,所以需要关掉这个验证程序 从日志里面可以看到LLC启动了一个Tiny.app的程序 只需要想办法把这个程序删掉即可 关机 按住 Command R 开机 进入R…

muduo异步日志库

文章目录 一、日志库模型1.前端 参考 一、日志库模型 组成部分 muduo日志库由前端和后端组成。 muduo日志库是异步高性能日志库,其性能开销大约是前端每写一条日志消息耗时1.0us~1.6us。 采用双缓冲区(double buffering)交互技术。基本思…

C语言文件操作(1)

C语言文件操作(1) 文章目录 C语言文件操作(1)一、理解文件1.概述2.分类①.正常角度②.文本文件和二进制文件 二、文件的打开和关闭1.流和标准流2.文件类型指针3.文件的打开和关闭以及使用类型 三、文件缓冲区 一、理解文件 1.概述…

【CSS】BFC 块级格式化上下文

1. 块级格式化上下文(BFC) 它是一块独立的渲染区域,规定该区域内,常规流块盒的布局。 先来说一下常规流块盒: 常规流块盒在水平方向上,必须盛满包含块常规流块盒在包含块的垂直方向上依次摆放常规流块盒…

GEO生信数据挖掘(九)肺结核数据-差异分析-WGCNA分析(900行代码整理注释更新版本)

第六节,我们使用结核病基因数据,做了一个数据预处理的实操案例。例子中结核类型,包括结核,潜隐进展,对照和潜隐,四个类别。第七节延续上个数据,进行了差异分析。 第八节对差异基因进行富集分析。…

yolov7改进优化之蒸馏(二)

续yolov7改进优化之蒸馏(一)-CSDN博客 上一篇已经基本写出来yolov7/v5蒸馏的整个过程,不过要真的训起来我们还需要进行一些修改。 Model修改 蒸馏需要对teacher和student网络的特征层进行loss计算,因此我们forward时要能够返回需…

PyTorch 与 TensorFlow:机器学习框架之战

深度学习框架是简化人工神经网络 (ANN) 开发的重要工具,并且其发展非常迅速。其中,TensorFlow 和 PyTorch 脱颖而出,各自在不同的机器学习领域占有一席之地。但如何为特定项目确定理想的工具呢?本综合指南[1]旨在阐明它们的优点和…

mysql—面试50题—1

注:面试50题将分为5个部分,每部分10题 一、查询数据 学生表 Student create table Student(SId varchar(10),Sname varchar(10),Sage datetime,Ssex varchar(10)); insert into Student values(01 , 赵雷 , 1990-01-01 , 男); insert into Student …

在Telegram营销后该如何进行客户管理

与目标客户进行接触之后,我们就要开始考虑后续怎么去销售自己的产品。这个过程可能是很漫长的,我们需要经常去联系对方,回答对方的疑问。但是现实中通常一个员工会手握多个账号,很难及时知道每个账号的信息,管理客户成…

ROI的投入产出比是什么?

ROI的投入产出比是什么? 投入产出比(Return on Investment, ROI)是一种评估投资效益的财务指标,用于衡量投资带来的回报与投入成本之间的关系。它的计算公式如下: 投资收益:指的是投资带来的净收入&#x…

系统可靠性分析与设计

系统可靠性分析与设计 内容提要 可靠性相关概念 骚戴理解:计算机系统的可靠性和可用性不是完全相同的概念,尽管它们在某些方面有重叠之处。 可靠性指的是计算机系统在特定时间段内正常运行的能力,即系统在面对各种故障或意外情况时能够继续…

程序设计(2023年10月)

函数传参有三种方式:值传递,地址传递,引用传递 排序算法:见下文八大排序 数据结构—八大排序_数据结构排序-CSDN博客

如何学会从产品经理角度去思考问题?

如何学会从产品经理角度去思考问题? 从产品经理的角度思考问题意味着你需要关注产品从构思到上市全过程中的各个方面,包括用户需求、市场趋势、设计、开发、测试、上市后的用户反馈等。以下是一些策略和方法,帮助你培养从产品经理角度思考问…

分类预测 | MATLAB实现SSA-CNN-BiLSTM-Attention数据分类预测(SE注意力机制)

分类预测 | MATLAB实现SSA-CNN-BiLSTM-Attention数据分类预测(SE注意力机制) 目录 分类预测 | MATLAB实现SSA-CNN-BiLSTM-Attention数据分类预测(SE注意力机制)分类效果基本描述模型描述程序设计参考资料 分类效果 基本描述 1.MAT…

Qt Signals Slots VS QEvents - Qt跨线程异步操作性能测试与选取建议

相关代码参考:https://gitcode.net/coloreaglestdio/qtcpp_demo/-/tree/master/qt_event_signal 1.问题的由来 在对 taskBus 进行低延迟改造时,避免滥用信号与槽起到了较好的作用。笔者在前一篇文章中,叙述了通过避免广播式地播发信号&…

行业模型应该如何去拆解?

行业模型应该如何去拆解? 拆解行业模型是一个复杂的过程,涉及对整个行业的深入分析和理解。下面是一些步骤和方法,可以帮助你系统地拆解行业模型: 1. 确定行业范围 定义行业:明确你要分析的行业是什么,包括…

QT计时器

widget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QTimerEvent> //计时器类 #include <QTime> //时间类 QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACEclass Widget : public QWidget {Q_OBJECTpublic:Widg…

【Proteus仿真】【Arduino单片机】蜂鸣器

文章目录 一、功能简介二、软件设计三、实验现象联系作者 一、功能简介 本项目使用Proteus8仿真Arduino单片机控制器&#xff0c;使用蜂鸣器等。 主要功能&#xff1a; 系统运行后&#xff0c;蜂鸣器播放音乐。 二、软件设计 /* 作者&#xff1a;嗨小易&#xff08;QQ&#x…