【Java多线程学习6】synchronized关键字

news2024/11/26 15:00:17

【Java多线程学习6】synchronized关键字

一、synchronized关键字是什么?有什么作用?

synchronized关键字是Java线程同步的关键字其可以修饰方法或代码块,并可以保证其修饰的方法代码块在任意时刻只能有一个线程执行

synchronized关键字使用主要有下面3种:

  • 修饰代码块
  • 修饰实例方法
  • 修饰静态方法

其中
synchronized关键字加到static静态方法和synchronized(class)代码块上都是给class类上锁。
synchronized关键字加到实例方法或synchronized(object)上是给对象实例上锁。

1、synchronized修饰代码块(锁指定对象/类)

    private static final Object object1 = new Object();
     public static void deal1() {
        //同步代码,获取对象锁
         synchronized (object1) {
            //需要同步的操作
        }
        
        //同步代码,获取class类锁
        synchronized (practice3.class) {
             //需要同步的操作
        }
    }

2、synchronized修饰实例方法(锁当前对象实例)

给当前对象实例加锁,进入同步代码前要获得当前对象实例的锁

    public synchronized void dealIt() {
        //需要同步的操作
    }

3、synchronized修饰静态方法(锁当前类)

当前类加锁,进入同步代码块前要获得当前class的锁(会作用于类的所有对象实例)。
因为静态成员不属于任何一个实例对象,归整个类所有,不依赖于类的特定实例,所以被类的所有实例共享。

    public synchronized static void dealIt() {
        //需要同步的操作
    }

问题思考1:

被synchronized修饰的静态方法和非静态方法之间调用互斥吗?
答:
不互斥,如果线程A调用的是实例对象所属的类的静态synchronized方法,线程B调用的是实例对象的非静态synchronized方法,是允许的,不会发生互斥现象,因为访问静态synchronized方法占用的锁是当前类的锁,而非静态synchronized方法所占用的锁是当前实例对象的锁

问题思考2:

构造方法可以使用synchronized修饰吗?
答:
构造方法不能使用synchronized关键字修饰
因为构造方法本身就属于线程安全的,不存在同步构造方法一说。

二、synchronized底层原理

1、对于synchronized同步代码块情况

public class synchronized1{
	public void deal() {
		synchronized(synchronized1.class) {
			System.out.println("Hello wys");
		}
	}
}

执行反编译,并查看反编译后的内容
在这里插入图片描述

在这里插入图片描述

说明:先将.java文件编辑为.class字节码文件,然后将.class文件反编译查看其反编译后的内容,反编译后的内容如下:
在这里插入图片描述
从上面反编译后的内容中我们可以看到:synchronized同步语句块是通过使用 monitorentermonitorexit两个指令。其中monitorenter指令指向同步代码块的开始位置monitorexit指令则指向同步代码块的结束位置

在执行monitorenter时,当前线程会尝试获取锁对象的monitor的持有权(对象监视器monitor),当monitor里的计数器为0就可以获取,并将计数器加1。如果当前线程获取锁失败,那当前线程就要阻塞等待,直到锁被另一个线程释放为止。

在执行monitorexit指令后,将锁计数器设为0,表示锁被释放,其他线程可以尝试获取锁。(注意:当前线程拥有锁对象才能执行monitorexit指令)

2、synchronized修饰方法的情况

public class synchronized1{
	public synchronized void deal1() {
			System.out.println("Hello wys");
	}
}

在这里插入图片描述
我们从反编译的结果可以看到,synchronized修饰方法并没有monitorenter指令和monitorexit指令,取而代之使用的是ACC_SYNCHRONIZED标识。该标识指明此方法为一个同步方法。JVM通过该标识ACC_SYNCHRONIZED标识来辨别一个方法是否为同步方法,从而进行相应的同步调用。

如果是实例方法,JVM会尝试获取实例对象的锁,如果是静态方法JVM会尝试获取当前class的锁。

总结:

  • 1、synchronized同步代码块底层实现是通过monitorentermonitorexit指令,其中monitorenter指令指向同步代码块的开始位置,monitorexit指令则指明同步代码块的结束位置。
  • 2、synchronized修饰方法并没有monitorenter和monitorexit指令,取而代之的是ACC_SYNCHRONIZED标识,该标识指明了该方法是一个同步方法。
  • 不过两者的本质都是对对象监视器monitor的获取。

三、synchronized和volatile有什么区别?

synchronized关键字 和 volatile关键字 两者是互补存在的而不是对立存在的

  • volatile关键字是线程同步的轻量级实现。volatile关键字可以保证变量的可见性,但是不能保证对变量操作的原子性。而synchronized关键字两者都能保证
  • volatile关键字只能修饰变量,而synchronized关键字可以修饰方法和代码块
  • volatile主要是用于解决多线程环境下变量的可见性,而synchronized主要是用于解决多线程环境下访问资源的同步性

四、JDK1.6之后synchronized底层做了哪些优化?

JDK1.6对锁的实现引入了大量的优化,如如偏向锁、轻量级锁、自旋锁、适应性自旋锁、锁消除、锁粗化等技术来减少锁操作的开销。

加入偏向锁和轻量锁后,锁就有四种状态级别由低到高:无锁-》偏向锁-》轻量级锁-》重量级锁。

具体详细优化内容后续文章介绍

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

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

相关文章

最优化:建模、算法与理论

最优化:建模、算法与理论 目前在学习 最优化:建模、算法与理论这本书,来此记录一下,顺便做一些笔记,在其中我也会加一些自己的理解,尽量写的不会那么的条条框框(当然最基础的还是要有&#xff…

读取文件和写入文件操作

在java中会涉及到对文件进行读取和写入操作,以下将介绍如何用java对文件进行读取和写入 读取 通过Readr读取字符流文件中的数据 读取字符流文件中的数据表示以字符为单位进行读取 package 文件操作;import java.io.*;/*** Created with IntelliJ IDEA.* Descript…

工具、技巧【个人专用】如何在CSND编辑器内输出带颜色的字体?Markdown编辑器——字体、字号、颜色使用全解

当你穿过了暴风雨,你就不再是原来那个人。 ————村上春树 🎯作者主页: 追光者♂🔥 🌸个人简介: 💖[1] 计算机专业硕士研究生💖 🌿[2] 2023年城市之星领跑者TOP1(哈尔滨)🌿 🌟[3] 2022年度博客之星人工智能领域TOP4dz

ruoyi-cloud-notes03

1、ExceptionHandler Spring的ExceptionHandler可以用来统一处理方法抛出的异常。 ExceptionHandler注解中可以添加参数,参数是某个异常类的class,代表这个方法专门处理该类异常 eg: 详细见Spring的ExceptionHandler注解 . 2、Accessors …

64位Office API声明语句第109讲

【分享成果,随喜正能量】你要做的是,果断拒绝那些给你制造不安的人,远离那些让你经常陷入负面情绪的人,失去他们,是你幸福的开始。。 跟我学VBA,我这里专注VBA, 授人以渔。我98年开始,从源码接…

rk3399移植linux kernel

rk3399移植linux kernel 0.前言一、移植ubuntu根文件系统二、移植linux1.支持NFS(可选)2.配置uevent helper3.支持etx4文件系统(默认已支持)4.配置DRM驱动5.有线网卡驱动6.无线网卡驱动 三、设备树四、内核镜像文件制作五、烧录六、总结 参考文章: 1.RK3399移植u-bo…

MySQL变量(二十七)

二八佳人体似酥,腰悬利剑斩愚夫,虽然不见人头落,暗里教君骨髓枯。 一. 变量 在MySQL数据库的存储过程和函数中,可以使用变量来存储查询或计算的中间结果数据,或者输出最终的结果数据。 在 MySQL 数据库中,变量分为系…

leetcode每日一练-第278题-第一个错误的版本

一、思路 二分查找——因为它可以快速地将版本范围缩小一半,从而更快地找到第一个坏版本。 二、解题方法 维护一个左边界 left 和一个右边界 right,在每一步循环中,我们计算中间版本 mid,然后检查它是否是坏版本。如果是坏版本…

【UE】AI导航,多个导航物体无法走到同一终点问题

如不需要开启导航物体的碰撞,则需要关闭Use RVOAvoidance 不然会导致多个导航物体无法到达同一个目标点,都在附近晃。无法结束寻路。 ue小白,判定导航终点的半径,没有找到。如果有大佬知道怎么设置请在评论区指出,谢…

Linux mmap系统调用视角看缺页中断

问题 1. mmap具体是怎么实现比read/write少一次内存copy的 2.mmap共享映射和私有映射在内核实现的时候到底有什么区别 3.mmap的文件映射和匿名映射在内核实现的时候到底有什么区别 4.父子进程的COW具体怎么实现的 概述 实际开发过程中经常使用或者看到mmap函数&#xff0…

实力认证!TDengine 入选 Gartner 中国数据分析与人工智能技术成熟度曲线

近日,国际权威研究机构 Gartner 发布了《2023 年中国数据分析及人工智能技术成熟度曲线》(即《Hype Cycle for Data, Analytics and AI in China, 2023》)报告,TDengine 成功入选实时数据管理领域代表产品。 作为评估全球新技术成…

HPRNet: Whole-Body 2D 姿态估计

HPRNet: Hierarchical Point Regression for Whole-Body Human Pose Estimation解析 摘要1. 简介2. Related Work2.1 Human Body Pose Estimation2.2 Whole-body Pose Estimation 3. Model3.1 全身关键点的层次回归3.2 足部关键点回归3.3 网络架构3.4 目标函数PCH and BKH >…

【MFC】05.MFC第一大机制:程序启动机制-笔记

MFC程序开发所谓是非常简单,但是对于我们逆向人员来说,如果想要逆向MFC程序,那么我们就必须了解它背后的机制,这样我们才能够清晰地逆向出MFC程序,今天这篇文章就来带领大家了解MFC的第一大机制:程序启动机…

《向量数据库指南》——Rockset 为实时数据库添加向量嵌入支持(一)

2023年4月18日,数据库供应商 Rockset 公布了对向量嵌入的支持,此举旨在使用户能够实时搜索和操作任何类型的数据。 位于加利福尼亚州圣马特奥的 Rockset 以前支持结构化和半结构化数据,让用户可以使用 SQL 和 NoSQL 实时搜索和分析数据。 现在,通过增加对向量嵌入的支持…

海康威视摄像头二次开发_云台控制_视频画面实时预览(基于Qt实现)

一、项目背景 需求:需要在公司的产品里集成海康威视摄像头的SDK,用于控制海康威视的摄像头。 拍照抓图、视频录制、云台控制、视频实时预览等等功能。 开发环境: windows-X64(系统) + Qt5.12.6(Qt版本) + MSVC2017_X64(使用的编译器) 海康威视提供了设备网络SDK,设备网…

2023暑假牛客多校6- E.Sequence

题目描述 You have an array of elements . For each task, you have three integers . Ask whether you can find an array of integers satisfy: are the multiplies of 2 Specially, if , it should satisfy is the multiply of 2 We define . If possible, print…

Java虚拟机怎样设置CLASSPATH的环境变量?

CLASSPATH环境变量用于保存一系列类包的路径,它和PATH环境变量的查看与配置方式完全相同。当Java虚拟机需要运行一个类时,会在CLASSPATH环境变量定义的路径下寻找所需的.class文件和类包。 为了让Java虚拟机能找到所需的class文件,就需要对C…

模拟实现消息队列项目(系列3) -- 服务器模块(硬盘管理)

目录 前言 1. 创建项目 2. 创建核心类 2.1 Exchange 2.2 MSQueue 2.3 Binding 2.4 Message 3. 数据库设计 3.1 SQLite 配置 3.2 Mapper层代码实现 3.2.1 创建表操作 3.2.2 交换机 队列 绑定的增加和删除 3.3 实现DataBaseManager 3.4 DataBaseManager单元测试 4.…

【JS】实现系统取色器

效果 使用环境说明 根据当前的信息,截至到 2023 年 8 月,以下是一些支持使用 new EyeDropper() 的主要浏览器(可能还有其他浏览器也提供了类似的功能): Google Chrome:从 Chrome 94 版本开始引入了 new Ey…

Linux下共享windows 一键搞定

编写脚本 [rootlocalhost ~]# vim dd.sh#!/bin/bash yum -y install samba mkdir -p /home/shar sss dddecho " [share]comment Shared Folderpath /homebrowseable yeswritable yesguest ok yes " > /etc/samba/smb.confchmod x /home/* useradd qqqq s…