栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

synchronized锁升级策略以及与ReentrantLock的区别

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

synchronized锁升级策略以及与ReentrantLock的区别

Synchronized 原理 基本特点(JDK8)
  1. 开始是乐观锁,如果冲突频繁,就转换为悲观锁
  2. 开始时轻量级锁实现,如果锁被持有的时间较长,则转换为重量级锁
  3. 实现轻量级锁的时候大概要用到自旋锁
  4. 是一种不公平锁
  5. 不是读写锁
加锁工作过程

JVM将synchronized锁分为无锁,偏向锁,轻量级锁,重量级锁状态。会根据竞争的激烈程度,动态选择锁的实现

无锁

没有任何线程尝试获取锁

偏向锁

当有第一个线程(t1)尝试获取锁,JVM分配偏向锁给t1线程。当这个t1线程再次获取锁时(重入或是再次执行),没有加锁和解锁的过程,从而降低程序的开销,就验证一下锁的持有线程是否是t1,若是直接放行。

轻量级锁

当有第二个线程(t2)在t1执行完后尝试获取锁,JVM就会取消偏向锁状态,将锁升级为轻量级锁。

使用CAS(自旋锁来实现)来进行轻量级锁的获取,有加锁和解锁的过程,就是通过自旋来进行的

t2线程尝试通过自旋的方式来获取轻量级锁,还有其他线程t3…t4在t2还没结束的时候尝试获取锁,都在自旋等待t2执行结束

重量级锁

当竞争非常激烈的时候,多个线程同时在竞争轻量级锁(一般来说就是当前线程数等于CPU核数的一半),或者自旋次数超过10次(默认值),也会将轻量级锁碰撞为重量级锁(竞争比较激烈,为了避免CPU空泡,就将线程阻塞)。

重量级锁是悲观锁的一种实现,依赖操作系统提供的mutex来实现,会从用户态切换到内核态,获取重量级锁失败的线程会进入阻塞状态。

ReentrantLock(可重入锁)

在java中除了synchronized关键字可以实现对象锁之外,java中的Lock接口的子类ReentrantLock也可以实现对象锁

ReentrantLock 的用法:
  • lock(): 加锁, 如果获取不到锁就死等.
  • trylock(超时时间):加锁,如果获取不到锁,等待一段时间后就放弃加锁
  • unlock():解锁
ReentrantLock 和 synchronized 的区别
  • synchronized是Java的关键字,由JVM实现,需要依赖操作系统提供的线程互斥原语(mutex)实现;ReentrantLock是Java标准库的一个类,基于Java实现,不依赖操作系统
  • synchronized由JVM自动加锁和解锁,不需要手动加锁和解锁。ReentrantLock需要手动加锁和解锁,使用起来更灵活,但也容易遗漏unlock
  • synchronized加锁失败会死等;ReentrantLock通过trylock方法等待一段时间就可以放弃等待
  • synchronized是非公平锁;ReentrantLock默认是非公平锁,可以通过可以通过构造方法传入一个 true 开启 公平锁模式
  • 更强大的唤醒机制. synchronized 是通过 Object 的 wait / notify 实现等待-唤醒. 每次唤醒的是一 个随机等待的线程. ReentrantLock 搭配 Condition 类实现等待-唤醒, 可以更精确控制唤醒某个指 定的线程.
  • ReentrantLock 和 synchronized都不支持读写锁,要想实现读写锁可以使用Lock子类ReentrantReadWriteLock
如何选择使用哪个锁?
  • 当竞争不激烈时,使用synchronized效率更高,自动释放锁
  • 当锁竞争激烈时,使用ReentrantLock搭配try lock更灵活控制加锁行为,而不是死等
  • 如果需要使用公平锁, 使用 ReentrantLock.
暑期编程PK赛 得CSDN机械键盘等精美礼品!
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1016892.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号