首页 > 其他分享 >谈谈你对Synchronized锁的理解

谈谈你对Synchronized锁的理解

时间:2024-09-20 17:52:59浏览次数:3  
标签:释放 Synchronized synchronized 代码 ReentrantLock 谈谈 理解 线程 修饰

一、什么是Synchronized同步锁

  1. synchronized是Java中用于实现线程安全的关键字,可以应用于方法或代码块上,用于实现线程安全的同步机制。
  2. synchronized控制多个线程对共享资源的访问,确保多个线程在同一时刻,只有一个线程可以执行某个方法或者代码块,保证了代码执行的一致性和原子性,防止出现数据不一致的情况。
  3. synchronized同步锁在加锁和解锁工程中,依赖于操作系统互斥锁(MutexLock)所实现的锁,小号资源,属于重量级锁。另外在获取锁时,必须一直等待,没有额外的尝试机制。

二、Synchronized关键字的用法

1. 修饰实例方法:synchronized修饰实例方法,则用到的锁,默认为 this 当前方法调用对象。

2. 修饰静态方法:synchronized修饰静态方法,则其所用的锁,默认为 Class 对象

3. 修饰代码块:synchronized修饰代码块,则其所用的锁,是某个指定的Java对象(自己指定锁对象)

三、Synchronized的底层实现

        synchronized代码块是由一对 monitorenter / monitorexit 指令实现,synchronized是通过对象的内部叫做监视器(monitor)来实现的,线程通过执行 monitorenter 指令尝试获取monitor的所有权,当monitor被占用时就会处于锁定状态。

四、锁升级(锁膨胀)

偏向锁:如果只有一个线程获得了锁,而且没有其他线程竞争,那么这个锁就会保持在偏向锁状态。如果发现有多于一个线程调用,再升级为轻量级锁。

轻量级锁:轻量级锁使用CAS(Compare and Swap)操作尝试获取锁,如果CAS成功,锁的持有者会变成当前线程;如果CAS失败(意味着其他线程正在尝试获取锁),当前线程将被挂起,并且锁会被升级为重量级锁。

重量级锁:需要在操作系统层面从用户态切换至内核态,实现操作系统级别的互斥锁,会带来额外性能的开销,降低效率。

五、Synchronized关键字的注意事项

        1. 当一个线程访问对象的一个  synchronized(this) 同步代码块时,另一个线程仍然可以访问该对象中的非 synchronized (this) 同步代码块。


        2.在没有加锁的情况下,所有的线程都可以自由地访问对象中的代码,而synchronized关键字只是限制了线程对于已经加锁的同步代码块的访问,并不会对其他代码做限制。所以,同步代码块应该越短小越好。


     3. 父类中 synchronized 修饰的方法,如果子类没有重写,则该方法仍然是线程安全性;如果子类重写,并且没有使用 synchronized 修饰,则该方法不是线程安全的;


4. 在定义接口方法时,不能使用 synchronized 关键字;


5. 构造方法不能使用 synchronized 关键字,但可以使用 synchronized 代码块来进行同步;


 6. 离开 synchronized 代码块后,该线程所持有的锁,会自动释放;

六、Synchronized和ReentrantLock的区别?

ReentrantLockSynchronized
锁实现机制AQS监视器Monitor
获取锁可以通过tryLock() 尝试获取锁,更灵活线程抢占模型
释放锁必须显示通过unlock()释放锁自动释放
锁类型支持公平锁和非公平锁非公平锁
可重入性可重入可重入

1. 用法上的区别:

  • synchronized 是一个关键字,可以用来修饰普通方法、静态方法以及代码块,语法简洁;
  • ReentrantLock是一个类,需要实例化,然后调用lock()和 unlock()方法来获取和释放锁;

2.获取和释放锁的机制:

  • synchronized 是自动加锁和释放锁的,当线程执行完 synchronized 代码块或者抛出异常时,锁会自动释放;
  • ReentrantLock 需要手动加锁和释放锁,如果在执行过程中发生异常而没有显式调用 unlock()方法释放锁,可能会导致死锁;

3.锁类型:

  • synchronized 默认是非公平锁,采用线程抢占模型:
  • ReentrantLock默认也是非公平锁,但可以通过构造函数指定为公平锁,这样可以提高锁的公平性,但是会降低性能;

4.底层实现:

  • synchronized是JVM级别的锁,通过监视器(Monitor)和JVM指令实现锁;
  • ReentrantLock 是基于 Java 类库提供的锁,使用了 AbstractQueuedSynchronizer(AOS)框架来实现锁的逻辑;

5.异常处理:

  • synchronized在发生异常时会自动释放锁,不会导致死锁;
  • ReentrantLock需要在 finally 块中显式调用 unlock()方法来释放锁,否则可能会导致死锁;

6.性能差异:

  • 早期版本的 Java中,ReentrantLock的性能优于synchronized
  • 但随着 Java 6 和后续版本中 synchronized 的优化,两者在性能上的差异已经不大;

7.功能扩展:

  • ReentrantLock 提供了更多功能:尝试获取锁(tryLock)、带超时的锁尝试、可中断的锁尝试,使用形式上更灵活:

标签:释放,Synchronized,synchronized,代码,ReentrantLock,谈谈,理解,线程,修饰
From: https://blog.csdn.net/weixin_65978343/article/details/142355167

相关文章

  • 深入理解Java对象结构
    一、Java对象结构实例化一个Java对象之后,该对象在内存中的结构是怎么样的?Java对象(Object实例)结构包括三部分:对象头、对象体和对齐字节,具体下图所示1、Java对象的三部分(1)对象头对象头包括三个字段,第一个字段叫作MarkWord(标记字),用于存储自身运行时的数据,例如GC标志位、哈希码......
  • 06-VIP-深入理解Mysql事务隔离级别与锁机制
    概述我们的数据库一般都会并发执行多个事务,多个事务可能会并发的对相同的一批数据进行增删改查操作,可能就会导致我们说的脏写、脏读、不可重复读、幻读这些问题。这些问题的本质都是数据库的多事务并发问题,为了解决多事务并发问题,数据库设计了事务隔离机制、锁机制、MVCC多版本并......
  • 深入理解Vue3中style的scoped
    概述scoped的作用就是样式模块化(CSSModule),即给组件每一个元素(以及非动态添加的子组件的根元素)加上一个data-v-xxxx的属性,样式选择器也会格式化成选择器[data-v-xxxx],这样就做到了样式隔离,每个组件内定义的样式只对该组件生效,避免了不同组件或页面的样式(选择器)冲突。本文......
  • 深入理解ConcurrentHashMap
    HashMap为什么线程不安全put的不安全由于多线程对HashMap进行put操作,调用了HashMap的putVal(),具体原因:假设两个线程A、B都在进行put操作,并且hash函数计算出的插入下标是相同的;当线程A执行完第六行由于时间片耗尽导致被挂起,而线程B得到时间片后在该下标处插入了元素,完成了正......
  • 深入理解ConcurrentHashMap
    HashMap为什么线程不安全put的不安全由于多线程对HashMap进行put操作,调用了HashMap的putVal(),具体原因:假设两个线程A、B都在进行put操作,并且hash函数计算出的插入下标是相同的;当线程A执行完第六行由于时间片耗尽导致被挂起,而线程B得到时间片后在该下标处插入了元素,完成了正......
  • 为什么寄存器需要建立时间和保持时间约束?——从门级角度理解
    目录1.建立时间与保持时间 2.从寄存器的内部结构理解建立时间与保持时间 2.1寄存器的结构 2.2主从锁存器构成的寄存器 2.3传输门构成的寄存器 3.查看寄存器的建立时间和保持时间  文章内容为博主学习记录,如有错误,欢迎在评论区指正。1.建立时间与保持......
  • LLM - 理解 多模态大语言模型(MLLM) 的 评估(Evaluation) 与相关技术 (六)
    欢迎关注我的CSDN:https://spike.blog.csdn.net/本文地址:https://spike.blog.csdn.net/article/details/142364884免责声明:本文来源于个人知识与公开资料,仅用于学术交流,欢迎讨论,不支持转载。评估(Evaluation)是研发多模态大语言模型(MLLM)的重要部分,也为模型的优化提......
  • 【c++基础知识——&引用的深度理解】
    C++引用深度理解对于一个函数来说,传值和传引用,在函数功能上没有区别,但在性能和副作用方面有显著差异。传值当按值传递参数时,函数会创建参数的一个副本。这样做的好处是函数内部对参数的修改不会影响原始变量,但缺点是对于大对象来说,拷贝操作会带来性能开销。传引用......
  • # 利刃出鞘_Tomcat 核心原理解析(十一)-- Tomcat 附加功能 WebSocket -- 3
    利刃出鞘_Tomcat核心原理解析(十一)--Tomcat附加功能WebSocket–3一、Tomcat专题-WebSocket-案例-OnMessage分析1、WebSocketDEMO案例实现流程分析:OnMessage分析2、在项目dzs168_chat_room中,在websocket类ChatSocket.java中,创建publicvoidonMes......
  • 最小二乘解的理解
    记录一下工作时遇到的拟合问题,将两个数据的关系建模为最小二乘的模型:\[y=a_0+a_1x+a_2x^2+a_3x^3+a_4x^4\]使用了python里面的numpy.linalg.lstsq函数进行拟合,以下是一个简单的示例importnumpyasnpimportmatplotlib.pyplotasplt#样本数据点x=np.a......