一文弄懂synchronized

简述

synchronized是什么?

synchronized 关键字是一种同步锁,它可以保证在一个时刻只有一个线程可以执行某段代码。synchronized 关键字可以用在方法、代码块、静态方法和静态代码块上。

synchronized怎么用?

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

  1. 修饰方法:当一个方法被synchronized修饰时,表示该方法是一个同步方法。同一时间只能有一个线程执行该方法,其他线程需要等待。
public synchronized void method() {// 这里是同步代码块
}
  1. 修饰代码块:当一个代码块被synchronized修饰时,表示该代码块是一个同步代码块。同一时间只能有一个线程进入该代码块,其他线程需要等待。
public class Example {public static void main(String[] args) {final int[] number = {1, 2, 3, 4, 5};for (int i = 0; i < 5; i++) {new Thread(() -> {synchronized (number) {// 这里是同步代码块System.out.println(number[i]);}}).start();}}
}

锁的是什么

普通同步方法>锁的是当前实力对象。
静态同步方法>锁的是当前类的Class对象。
同步方法快>锁的是synchonized括号里配置的对象。

注意事项

当使用synchronized修饰代码块时,应该尽量控制同步代码块的范围,避免锁的竞争过于频繁,以提高程序的性能。同时,锁对象的选择也很重要,应该选择合适的锁对象以避免不必要的线程等待和资源竞争。

原理

synchronized修饰代码块和方法的底层原理类似,都是通过对象头中的锁标记位来实现的。

修饰方法

进入方法:当线程调用一个被synchronized修饰的方法时,会尝试获取该方法所属对象的锁。
获取锁:如果对象的锁标记位为"unlocked"状态,则当前线程可以获取到锁,并将锁标记位设置为"locked"状态,表示该对象被当前线程锁定。
执行方法体:线程获取到锁后,会执行synchronized修饰的方法体中的代码。
释放锁:当方法执行完毕或抛出异常时,会自动释放对象的锁,将锁标记位重新设置为"unlocked"状态。

注意点

需要注意的是,synchronized修饰方法时,默认锁定的是当前对象实例(this),即当前方法所属的对象。如果是静态方法,锁定的是当前类的Class对象。

//1.静态方法 
public static synchronized void method() {// 该方法被当前类的Class对象锁定// ...
}
//2.普通方法
public synchronized void method() {// 该方法被当前实例对象锁定// ...
}

修饰代码块

进入代码块:当线程进入一个被synchronized修饰的代码块时,会尝试获取对象的锁。
获取锁:如果对象的锁标记位为"unlocked"状态,则当前线程可以获取到锁,并将锁标记位设置为"locked"状态,表示该对象被当前线程锁定。
阻塞或执行:如果对象的锁标记位为"locked"状态,表示该对象已被其他线程锁定。当前线程会被阻塞,直到锁标记位变为"unlocked"状态时才能继续执行。
释放锁:当线程执行完synchronized代码块后,会释放对象的锁,将锁标记位重新设置为"unlocked"状态,使其他线程能够获取到锁并执行。

public void method() {synchronized (lock) {// 该代码块被lock对象锁定// ...}
}

锁的高级特征

JVM在实现锁的过程中采用了多种锁的机制,包括偏向锁、轻量级锁和重量级锁,并且会根据锁竞争的情况自动进行锁升级和降级。下面是对这些锁的机制和锁升级的简要说明:

偏向锁(Bias Locking):

简介

偏向锁是一种乐观锁策略,适用于大部分情况下只有一个线程对锁进行竞争的场景。
偏向锁的目标是减少无竞争的情况下对锁的开销,提高程序的性能。
当一个线程获取到偏向锁后,JVM会将线程的标识记录在对象头中,之后该线程再次获取锁时无需进行同步操作,从而提高了程序的执行效率。

实现原理

轻量级锁(Lightweight Locking):

简介

当多个线程对同一个锁进行竞争时,JVM会将锁升级为轻量级锁。
轻量级锁使用CAS(Compare and Swap)操作来实现对锁的获取和释放,避免了线程阻塞和唤醒的开销。
如果竞争激烈,多个线程同时尝试获取锁,那么轻量级锁会膨胀为重量级锁。

实现原理

重量级锁(Heavyweight Locking):

简介

当轻量级锁膨胀失败或竞争过于激烈时,JVM会将锁升级为重量级锁。
重量级锁使用操作系统的互斥量来实现对锁的获取和释放,需要涉及线程的阻塞和唤醒。
线程在获取重量级锁时会进入阻塞状态,当锁被释放时,JVM会从阻塞的线程中选择一个进行唤醒。
锁的升级和降级是根据锁竞争的情况动态进行的,以提高程序的性能和吞吐量。当JVM检测到锁竞争较少时,会尝试将重量级锁降级为轻量级锁,以提高并发性能。反之,如果锁竞争激烈,JVM会将轻量级锁膨胀为重量级锁,以避免不必要的自旋和消耗。

实现原理

需要注意的是,锁的升级和降级过程对于开发者来说是透明的,无需手动干预。JVM会根据实际情况自动进行锁的升级和降级操作,以达到更好的性能和可伸缩性。

这些锁的机制和锁升级是JVM内部的实现细节,对于开发者来说,只需要了解它们的存在和基本原理,以正确地使用synchronized关键字来实现线程安全的同步。

优秀文章传送门:
https://zhuanlan.zhihu.com/p/571793506
在这里插入图片描述

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

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

相关文章

Android和JNI交互 : 常见的图像格式转换 : NV21、RGBA、Bitmap等

1. 前言 最近在使用OpenCV处理图片的时候&#xff0c;经常会遇到需要转换图像的情况&#xff0c;网上相关资料比较少&#xff0c;也不全&#xff0c;有时候得费劲老半天才能搞定。 自己踩了坑后&#xff0c;在这里记录下&#xff0c;都是我在项目中遇到的图像转化操作&#xf…

AI开源 - LangChain UI 之 Flowise

原文&#xff1a;AI开源 - LangChain UI 之 Flowise 一、Flowise 简介 Flowise 是一个为 LangChain 设计的用户界面(UI)&#xff0c;使得使用 LangChain 变得更加容易&#xff08;低代码模式&#xff09;。 通过拖拽可视化的组件&#xff0c;组建工作流&#xff0c;就可以轻…

ScrapeKit库中Swift爬虫程序写一段代码

以下是一个使用ScrapeKit库的Swift爬虫程序&#xff0c;用于爬取网页视频的代码&#xff1a; import ScrapeKit// 创建一个配置对象&#xff0c;用于指定爬虫ip服务器信息 let config Configuration(proxyHost: "duoip", proxyPort: 8000)// 创建一个爬虫对象 let s…

diffusers-Load pipelines,models,and schedulers

https://huggingface.co/docs/diffusers/using-diffusers/loadinghttps://huggingface.co/docs/diffusers/using-diffusers/loading 有一种简便的方法用于推理是至关重要的。扩散系统通常由多个组件组成&#xff0c;如parameterized model、tokenizers和schedulers&#xff0c…

Spring-Spring 之底层架构核心概念解析

BeanDefinition BeanDefinition表示Bean定义&#xff0c;BeanDefinition中存在很多属性用来描述一个Bean的特点。比如&#xff1a; class&#xff0c;表示Bean类型scope&#xff0c;表示Bean作用域&#xff0c;单例或原型等lazyInit&#xff1a;表示Bean是否是懒加载initMeth…

LeetCode 421. 数组中两个数的最大异或值

原题链接&#xff1a;https://leetcode.cn/problems/maximum-xor-of-two-numbers-in-an-array/description/?envTypedaily-question&envId2023-11-04 题目分析 异或且时间复杂度在nlogn内第一反应想到字典树&#xff0c;扫一遍存进字典树&#xff0c;然后遍历每个数&…

【Git企业开发】第四节.Git的分支管理策略和bug分支

文章目录 前言一、Git的分支管理策略 1.1 Fast forward 模式和--no-ff 模式 1.2 企业分支管理策略二、bug分支三、删除临时分支四、总结总结 前言 一、Git的分支管理策略 1.1 Fast forward 模式和--no-ff 模式 通常合并分支时&#xff0c;如果可能&#xff0c;Git 会…

AI:51-基于深度学习的电影评价

🚀 本文选自专栏:AI领域专栏 从基础到实践,深入了解算法、案例和最新趋势。无论你是初学者还是经验丰富的数据科学家,通过案例和项目实践,掌握核心概念和实用技能。每篇案例都包含代码实例,详细讲解供大家学习。 📌📌📌本专栏包含以下学习方向: 机器学习、深度学…

【CSS】div 盒子居中的常用方法

<body><div class"main"><div class"box"></div></div> </body>绝对定位加 margin: auto; &#xff1a; <style>* {padding: 0;margin: 0;}.main {width: 400px;height: 400px;border: 2px solid #000;positio…

C++prime之输入输出文件

作为一种优秀的语言&#xff0c;C必然是能操作文件的&#xff0c;但是我们要知道&#xff0c;C是不直接处理输入输出的&#xff0c;而是通过一族定义在标准库中的类型来处理IO的。 ‘流’和‘缓冲区’ ‘流’和‘缓冲区’ C程序把输入输出看作字节流&#xff0c;并且其只检查…

Microsoft Dynamics 365 CE 扩展定制 - 5. 外部集成

本章内容包括: 使用.NET从其他系统连接到Dynamics 365使用OData(Java)从其他系统连接到Dynamics 365使用外部库从外部源检索数据使用web应用程序连接到Dynamics 365运行Azure计划任务设置Azure Service Bus终结点与Azure Service Bus构建近乎实时的集成使用来自Azure服务总线…

接口测试入门,如何划分接口文档

1.首先最主要的就是要分析接口测试文档&#xff0c;每一个公司的测试文档都是不一样的。具体的就要根据自己公司的接口而定&#xff0c;里面缺少的内容自己需要与开发进行确认。 我认为一针对于测试而言的主要的接口测试文档应该包含的内容分为以下几个方面。 a.具体的一个业…

selenium自动化测试入门 —— 设置等待时间

time.sleep(3) 固定等待3秒 driver.implicitly_wait(10) 隐性的等待&#xff0c;对应全局 WebDriverWait( driver, timeout).until(‘有返回值的__call__()方法或函数’) 显性的等待&#xff0c;对应到元素 一、time.sleep(seconds) 固定等待 import time time.sleep(3) #…

axios 全局错误处理和请求取消

这两个功能都是用拦截器实现。 前景提要&#xff1a; ts 简易封装 axios&#xff0c;统一 API 实现在 config 中配置开关拦截器 全局错误处理 在构造函数中&#xff0c;添加一个响应拦截器即可。在构造函数中注册拦截器的好处是&#xff0c;无论怎么实例化封装类&#xff0c…

基础课19——客服系统知识库的搭建流程

1.收集整理业务数据 注意&#xff1a;我们在做业务数据收集时&#xff0c;往往是甲方提供给我们的&#xff0c;这时就需要确定一个标准&#xff0c;否则对知识库梳理工作会带来很大的难度&#xff0c;建议和甲方沟通确认一个双方都统一的知识库原材料。 2.创建知识库 在创建知…

Docker基础(简单易懂)

目录 一、docker是什么 核心概念 二、docker安装 1、卸载docker 2、使用yum 安装 三、docker常用命令 1、帮助命令 2、镜像命令 1&#xff09;查看镜像 2&#xff09;查询镜像 3&#xff09;拉取镜像 4&#xff09;删除镜像 3、容器命令 四、容器数据卷 五、Dock…

深度学习之基于Tensorflow人脸面部表情识别系统

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 文章目录 一项目简介 二、功能三、系统四. 总结 一项目简介 基于Tensorflow的人脸面部表情识别系统是一种基于深度学习技术的图像处理应用&#xff0c;该系统主要通过人脸图像数…

CoCa论文笔记

摘要 计算机视觉任务中&#xff0c;探索大规模预训练基础模型具有重要意义&#xff0c;因为这些模型可以可以极快地迁移到下游任务中。本文提出的CoCa&#xff08;Contrastive Captioner&#xff09;&#xff0c;一个极简设计&#xff0c;结合对比损失和captioning损失预训练一…

Zabbix如何监控腾讯云NAT网关

1、NAT网关介绍 NAT 网关&#xff08;NAT Gateway&#xff09;是一种支持 IP 地址转换服务&#xff0c;提供网络地址转换能力&#xff0c;主要包括SNAT&#xff08;Source Network Address Translation&#xff0c;源网络地址转换&#xff09;和DNAT&#xff08;Destination N…

如何使用Python和Matplotlib创建双Y轴动态风格折线图 | 数据可视化教程

前言 我的科研论文中需要绘制一个精美的折线图&#xff0c;我的折线图中有三条曲线&#xff0c;分别表示期望角速度指令信号&#xff0c;和实际的角速度信号&#xff0c;还有实际的航向角信号&#xff0c;现在我已经拥有了数据&#xff0c;使用Python中matplotlib.plt.plot来直…