Synchronized同步锁

news2024/11/16 3:20:03

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.coloradmin.cn/o/1125816.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Java Netty - Buffer类

Buffer类 当应用程序进行数据传输的时候,往往需要使用缓冲区,常用的缓存区就是JDK NIO类库提供的 java.nio.Buffer; NIO的Buffer本质上是一个内存块,既可以写入数据,也可以从中读取数据; 其中,…

IP地址定位是什么?有哪些优缺点?

IP地址定位是一种用于确定设备或用户地理位置的方法,具有一些明显的优点和缺点。以下是IP地址定位的优缺点: 优点: 广泛适用性: IP地址定位适用于几乎所有与互联网连接的设备,包括计算机、智能手机、平板电脑和物联网…

全链路压测专题---2、全链路压测架构和技术

如何开展全链路压测 业务模型梳理 首先应该将核心业务和非核心业务进行拆分,确认流量高峰针对的是哪些业务场景和模块,针对性的进行扩容准备梳理出对外的接口:使用MOCK(模拟)方式做挡板千万不要污染正常数据&#xf…

包装类知识.JDK7,JDK8相关时间类练习

包装类 包装类:基本数据类型对应的引用类型 JDK5之前的Integer包装类 如下 了解即可 i5传入的值 第一个是字符串,第二个是进制数.为83是因为再打印的时将123看成8进制了 然后打印转化为10进制 区别对比 public static void main(String[] args) {Integer i1 Integer.valu…

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

本文是我们《手把手教你接口性能测试》系列文章中的中篇,主要介绍软件测试工作中常用的一些接口测试工具。 一、接口都有哪些类型? 1、接口一般分为两种: 1.程序内部的接口 2.系统对外的接口 程序内部的接口 方法与方法之间,模…

最靠谱的nvm安装教程 for mac

nvm是node 版本管理工具 一、前提 1、保证自己的mac电脑上没安装node环境 2、保证自己的电脑上有安装git,不然下载nvm时会报错。 git下载可以参考: 1)佛系安装:通过提示下载 XCode 2)brem安装 3)终极大法&…

Kubernetes - 一键安装部署 K8S(附:Kubernetes Dashboard)

问题描述 不知道大伙是如何安装 K8s,特别还是集群的时候,我上一次安装搭建的时候,那个恶心到我了,真的是一步一个脚印走完整个搭建流程,爬了不少坑。 于是,才有了今天的文章,到底有没有可以一…

在mybatis的xml中使用枚举来做判断条件

1.枚举类 import com.baomidou.mybatisplus.annotation.IEnum; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonValue; import com.shinkeer.common.utils.StringUtils;import java.util.HashMap; import java.util.Map;…

日志logback详解

该篇博客是我参考了很多博客总结出来的,内容很多,你能看完不睡着算你厉害! 一、日志框架发展史 二、日志规范 三、日志级别 四、Logback 4.1 Maven引入 4.2 logback-spring.xml是在哪里加载的? 4.3 logback.xml和logback-s…

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

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

抖音SEO优化怎么做?详细的方法来了,搭配批量剪辑让效果更优

抖音作为一个非常受欢迎的短视频平台,无论是用户还是内容创作者,体量都越来越大,这意味着竞争也越来越大,想要在抖音上获得更多的曝光和关注,做好抖音 SEO 优化是一门必修课。 抖音 SEO 优化是指优化我们发布到抖音平…

AMEYA360:瑞萨电子转矩控制解决方案加强工业自动化

随着科技的不断进步和全球制造业的竞争加剧,越来越多的企业开始投资和采用自动化技术,以提高生产效率、降低成本、改善产品质量并确保过程安全。而为协同工作完成复杂任务,确保高质量的生产结果。工业自动化设备对精度控制要求非常高&#xf…

Redis底层核心数据结构详解

文章目录 一、深入String(SDS)1. 字符串简介2. SDS存在的意义3. SDS结构设计4. SDS与C字符串的区别4.1 常数复杂度获取字符串长度4.2 杜绝缓冲区溢出4.3 二进制安全4.4 SDS API 5 小结 二、深入List (QuickList)1. 链表节点结构设计2. Redis的链表实现的…

linux驱动开发led绑定亮灯

head.h 应用程序 驱动程序 结果

LabVIEW基于机器视觉的钢轨表面缺陷检测系统

LabVIEW基于机器视觉的钢轨表面缺陷检测系统 机器视觉检测技术和LabVIEW软件程序,可以实现轨道工件的表面质量。CMOS彩色工业相机采集的图像通过图像预处理、图像阈值分割、形态分析、特征定位和图案匹配进行处理和分析。图形显示界面采用LabVIEW软件编程设计&…

【大模型的一些基本结论】

这里写自定义目录标题 LLama的一些基本结论 各个论文中给出一些观察显现,我们比摘要更简略地摘要一些文本大模型大佬地基本结论和观察到的现象 LLama的一些基本结论 由于大模型要作为服务,因而推理时间更重要。一个较小的、训练时间较长的模型最终会在…

GLIP,FLIP论文阅读

Scaling Language-Image Pre-training via Masking(FLIP,2023)👍 贡献: 1.图像端引入MAE的随机MASK,image encoder只处理未mask的patches(和之前的MAE方法一致),减少了输…

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

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

QUIC协议包头保护(四)

一:为什么要有包头保护 学过HTTP和HTTPS都知道,随着网络的普及,人们对于信息的保护,个人的隐私越发的重视。信息加密对于未来协议的发展肯定是越来越趋于严格。QUIC作为新生代的协议,必然要站着前辈的肩膀上发展&#…

基于Python实现的复制、移动、离线化你的 Markdown 文档,清理 Markdown 引用路径中的垃圾文件

Markdown 工具箱 完整代码下载地址: Markdown 工具箱 🚩 简介 Markdown 工具箱,是我为 Markdown 笔记管理做的一个工具集。目前有以下几个功能: 复制 批量将 md 笔记(连带它的相对路径引用的图片、附件)…