谈谈synchronized关键字

synchronized是什么?

synchronized为同步之意,可保证在同一时刻,被它修饰的方法或代码块只能有一个线程执行,它的使用解决了并发多线程中的三大问题:原子性、可见性、顺序性

有的书籍中可能会看到说synchronized是一种重量级锁,性能差,不建议在代码中使用,其实这是早期的synchronized特点,自JDK1.6之后,synchronized 引入了大量的优化如自旋锁、适应性自旋锁、锁消除、锁粗化、偏向锁、轻量级锁等技术来减少锁操作的开销,这些优化让 synchronized 锁的效率提升了很多。因此, synchronized 在JDK 源码、很多开源框架都大量使用了 synchronized 。

synchronized的使用

synchronized在Java中主要的3种使用方式:

  1. 修饰实例方法: 为当前对象实例加锁,进入同步方法需要先获取对象锁;

  2. 修饰静态方法: 为当前类加锁,锁定的是Class对象,进入同步方法需要先获取类锁;

  3. 修饰代码块:  为指定对象加锁,进入同步方法需要先获取指定对象的锁。

样例:

//修饰实例方法,为当前实例加锁
synchronized void method() {
    //业务代码
}
//修饰静态方法,锁为当前Class对象
synchronized static void method() {
    //业务代码
}
//修饰代码块,锁为括号里面的对象
synchronized(this) {
    //业务代码
}

这里有几个问题:

1:synchronized修饰代码块可以给类加锁吗?

可以,前面说了修饰代码块时,是给代码中的对象加锁,这里面的对象既可以是实例也可以是类。

2:静态 synchronized 方法和非静态 synchronized 方法之间的调用互斥吗?

不互斥,如果线程A调用一个实例对象的非静态synchronized方法,线程B同时去调用这个实例对象所属类的静态synchronized方法并不会发生互斥,因为线程A此时拿到的是实例对象锁,而线程B拿到的是当前类的锁。

3:构造方法可以用 synchronized 修饰吗?

不可以,构造方法本身就是线程安全的,在Java开发规范里也明确告诉我们。

构造方法不能是抽象的(abstract)、静态的(static)、最终的(final)、同步的(synchronized)。

synchronized的底层原理

在synchronized的底层(JVM层面),针对方法与代码块的实现逻辑是不同的,因此我们在分析底层原理时也要分别来看。

1、当synchronized修饰方法时

public class Test {
    public synchronized void method() {
        System.out.println("synchronized 方法");
    }
}

我们通过对编译后的class文件进行反编译后,分析其底层实现。

知识点扩展:我们通过javap命令进行反编译,javap是Java class文件分解器,可以反编译,也可以查看java编译器生成的字节码等。javap参数如下:

使用方式,既可以在电脑的命令行提示符中使用,也可以通过idea的terminal终端使用,参考命令:javap -c -v Test.class 

反汇编结果

由上图可看出同步方法通过加 ACC_SYNCHRONIZED 标识实现线程的执行权的控制,如果修饰的是实例方法,JVM会获取对象锁,如果修饰的是静态方法,JVM会获取当前类锁。 

2、当synchronized修饰代码块时

public class Test {
    public void method() {
        synchronized (this) {
            System.out.println("synchronized");
        }
    }
}

 反汇编结果

与同步方法不同,同步代码块中使用了monitorenter 和 monitorexit 指令,其中 monitorenter 指令指向同步代码块的开始位置,monitorexit 指令则指明同步代码块的结束位置,并且monitorexit标识有2个,以保证在正常执行和异常情况下均可释放锁。

在命令执行到monitorenter时,线程会去尝试获取对象的锁。

 

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

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

相关文章

用vscode调试cpp程序相关操作记录

需要在服务器上用vscode调试cpp程序,写此记录launch.json配置和相关步骤错误导致的问题 1.在需要运行程序的服务器上安装C/C Extension Pack(之前只在本地装了),可以支持调试C/C应用程序(设置断点,单步执行&#xff0c…

【计算机视觉】Gaussian Splatting源码解读补充(二)

第一部分 本文是对学习笔记之——3D Gaussian Splatting源码解读的补充,并订正了一些错误。 目录 三、相机相关scene/cameras.py:class Camera 四、前向传播(渲染):submodules/diff-gaussian-rasterization/cuda_rast…

【java数据结构】基于java提供的ArrayList实现的扑克牌游戏-(附源码~)

【Java数据结构】基于java泛型实现的二维数组完成三人扑克游戏 基本框架的实现创建一副牌如何进行洗牌:每个人抓的牌放到哪里: 源码具体实现cardcardsTest 个人简介:努力学编程 每日鸡汤:stay foolish,stay hungry-史蒂芬.乔布斯斯…

springboot+vue 的图书个性化推荐系统的设计与实现

图书个性化推荐系统的主要使用者分为管理员和学生,实现功能包括管理员:首页、个人中心、学生管理、图书分类管理、图书信息管理、图书预约管理、退换图书管理、管理员管理、留言板管理、系统管理,学生:首页、个人中心、图书预约管…

适用于 Windows PC 的 6 款最佳照片恢复软件

您想向您的朋友展示您上个月访问迈阿密海滩的照片。可惜!您的 Windows 计算机中不再有照片文件夹。不仅是这个文件夹,您还发现您的许多重要和有趣时刻的照片都丢失了!这意味着您丢失了许多家庭成员、可爱宝宝的珍贵照片或毕业典礼等难忘活动的…

利用Base64加密算法将数据加密解密

1. Base64加密算法 Base64准确来说并不像是一种加密算法,而更像是一种编码标准。 我们知道现在最为流行的编码标准就是ASCLL,它用八个二进制位(一个char的大小)表示了127个字符,任何二进制序列都可以用这127个字符表…

chap验证实验

一、添加接口 在每个路由器里添加2SA接口 二、配IP 进入serial接口配置IP R1: R2: ppp mp Mp-group 0/0/0 R3: 查看: 三、aaa认证,chap验证 创建一个新用户: R2进入3/0/0接口: R1进入3/0/0接口&a…

制作一个RISC-V的操作系统六-bootstrap program(risv 引导程序)

文章目录 硬件基本概念qemu-virt地址映射系统引导CSR![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/86461c434e7f4b1b982afba7fad0256c.png)machine模式下的csr对应的csr指令csrrwcsrrs mhartid引导程序做的事情判断当前hart是不是第一个hart初始化栈跳转到c语言的…

【Android开发】【创建Activity,Activity之间的切换/消息传递】【java】

一、第一个Activity 1.1 创建一个空Activity 1.2 创建一个布局 知识点 在XML中引用一个id:id/id_name 在XML中定义一个id:id/id_name 右键错误,点击Show Quick-Fixes,再点击弹出的Suppress:Add........,错误会被自动修…

详细分析PyAutoGUI中的locate函数(附Demo)

目录 前言1. 基本知识2. 源代码分析3. Demo 前言 起因是实战中locate对个别定位会有偏差,导致一直识别错误 相应的基本知识推荐阅读:详细分析Python中的Pyautogui库(附Demo) 1. 基本知识 pyautogui.locate()函数用于在屏幕上定…

DBO优化朴素贝叶斯分类预测(matlab代码)

DBO-朴素贝叶斯分类预测matlab代码 蜣螂优化算法(Dung Beetle Optimizer, DBO)是一种新型的群智能优化算法,在2022年底提出,主要是受蜣螂的的滚球、跳舞、觅食、偷窃和繁殖行为的启发。 数据为Excel分类数据集数据。 数据集划分为训练集、验证集、测试…

YOLO-v8-seg实例分割使用

最近需要实例分割完成一些任务,一直用的SAM(segment anything)速度慢,找一个轻量分割模型。 1. YOLO-v8-seg使用 git clone https://github.com/ultralytics/ultralytics.git cd ultralytics vim run.py from ultralytics import YOLO# L…

鸿蒙一次开发,多端部署(十三)功能开发的一多能力介绍

应用开发至少包含两部分工作: UI页面开发和底层功能开发(部分需要联网的应用还会涉及服务端开发)。前面章节介绍了如何解决页面适配的问题,本章节主要介绍应用如何解决设备系统能力差异的兼容问题。 系统能力 系统能力&#xff…

RK3568驱动指南|第十三篇 输入子系统-第143章 多对多的匹配关系分析

瑞芯微RK3568芯片是一款定位中高端的通用型SOC,采用22nm制程工艺,搭载一颗四核Cortex-A55处理器和Mali G52 2EE 图形处理器。RK3568 支持4K 解码和 1080P 编码,支持SATA/PCIE/USB3.0 外围接口。RK3568内置独立NPU,可用于轻量级人工…

有哪些强大好用的AI表格数据处理工具或者 AI Excel工具?

在繁忙的工作和生活中,处理大量的表格数据往往令人感到头疼。面对一列列数字、一行行文字,我们需要花费大量的时间和精力去整理、核对。然而,随着科技的飞速发展,人工智能(AI)技术正逐渐改变这一现状。 如…

LLM 面试知识点——模型基础知识

1、主流架构 目前LLM(Large Language Model)主流结构包括三种范式,分别为Encoder-Decoder、Causal Decoder、Prefix Decode。对应的网络整体结构和Attention掩码如下图。 、 各自特点、优缺点如下: 1)Encoder-Decoder 结构特点:输入双向注意力,输出单向注意力。 代表…

Flutter开发进阶之瞧瞧RenderObject

Flutter开发进阶之瞧瞧RenderObject 通过上回我们了解到Flutter执行buildTree的逻辑线,当Tree构建完成后会交给Flutter底层的渲染事件循环去执行将内容渲染到屏幕的操作。 但是渲染的操作到底是如何串起来的呢?这篇文章将会从Element联系到RenderObject…

点餐小程序php毕设项目

主要技术框架: 主要功能模块: 商品管理 订单管理 用户管理 优惠券管理 商品分类管理 评论管理 轮播图管理 截图 获取源码 https://blog.lusz.top/article?article_id-2

【Linux系统编程(进程编程)】创建进程的场景,fork和vfork的使用及区别

文章目录 一、进程关键概念二、创建进程函数fork的使用一、进程创建实战 三、创建进程函数fork的使用补充四、进程创建发生了什么事?五、创建新进程的实际应用场景 & fork总结一、fork创建一个子进程的一般目的?二、fork编程实战 六、vfork也能创建进…

grid布局

文章目录 1. 概念2. 组成2.1. 网格行2.2. 网格列2.3. 网格间距2.4. 网格线2.5. 网格容器2.6. fr 单位 3. 网格跨行跨列3.1. 跨列3.2. 跨行 4. 网格布局案例4.1. 演示效果4.2. 分析思路4.3. 代码实现 1. 概念 网格是一组相交的水平线和垂直线,它定义了网格的列和行。…