synchronize&Lock

synchronize

synchronize内置锁是一种对象锁(锁的是对象而非引用),作用粒度是对象,可以用来实现对临界资源的同步互斥访问,是可以重入的。

加锁的方式
  • 同步实例方法,锁的是当前对象
  • 同步类方法,锁的是当前类对象
  • 同步代码块,锁的是括号里的对象
synchronize底层原理
  • synchronized是基于JVM内置锁实现,通过内部对象Monitor(监视器锁)实现,基于进入与退出Monitor对象实现方法与代码块同步,监视器锁的实现依赖底层操作系统的Mutex lock(互斥锁)实现,它是一个重量级锁性能较低。当然,JVM内置锁在1.5之后版本做了重大的优化,如锁粗化(Lock Coarsening)、锁消除(Lock Elimination)、轻量级锁(Lightweight Locking)、偏向锁(Biased Locking)、适应性自旋(Adaptive Spinning)等技术来减少锁操作的开销,,内置锁的并发性能已经基本与Lock持平。
  • synchronized关键字被编译成字节码后会被翻译成monitorenter 和 monitorexit
    两条指令分别在同步块逻辑代码的起始位置与结束位置。
对象头
  • 对象头包括两部分信息,第一部分是“Mark Word”,用于存储对象自身的运行时数据,如哈希码、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等等,它是实现轻量级锁和偏向锁的关键,大小为32Bits(64位会开启指针压缩)。
锁的膨胀升级过程

锁的状态一共有四种,无锁状态、偏向锁、轻量级锁和重量级锁。随着锁的竞争,锁可以从偏向锁升级到轻量级锁,再升级到重量级锁,锁的升级是单向的,也就是说只能从低到高升级,不会出现锁的降级。

  • 偏向锁:为了减少同一线程获取锁的代价而引入偏向锁。一个线程执行时是偏向锁,当线程再获取锁时,无需再做任何同步操作,即获取锁的过程,省去了大量有关锁的申请的操作。
  • 轻量级锁:适用于线程交替执行同步块的场合,竞争并不是很激烈的场合。
  • 自旋锁:轻量级锁失效后,还会进行一种自旋锁的优化手段。适用与线程持有锁的时间不会太长的场景,让线程做几个空循环,一段时间后如果获取到锁,就执行代码块,如果获取不到,就升级为重量级锁。
  • 锁消除:虚拟机在编译时会对通过对运行上下文的扫描,去除不可能存在共享资源竞争的锁,通过这种方法消除没有必要的锁,节省无意义的请求锁时间。锁消除依赖的依据是逃逸分析的数据支持。
    锁消除,前提是java必须运行在server模式(server模式会比client模式作更多的优化),同时必须开启逃逸分析
    -XX:+DoEscapeAnalysis 开启逃逸分析
    -XX:+EliminateLocks 表示开启锁消除。
  • 锁粗化:当有连续的同步代码块时会将其合并成一个代码块。
    在这里插入图片描述
逃逸分析
  • 同步省略。如果一个对象被发现只能被一个线程访问到,那么对于这个对象的操作可以不考虑同步。
  • 将堆内存分配转化为栈分配。如果一个对象在子程序中被分配,要使该对象的指针永远不会逃逸,对象可能是栈分配的候选,而不是堆分配。
  • 分离对象或标量替换。有的对象可能不需要作为一个连续的内存结构存在也可以被访问到,那么对象的部分可以不存储在内存,而是存储在寄存器中。
    从jdk1.7之后默认开启逃逸分析。
Lock
ReentrantLock

ReentrantLock是一种基于AQS框架的应用实现,类似于synchronize是一种互斥锁,可以保证线程安全。而它具有比synchronize更多的特性,如支持手动加锁和解锁,支持加锁的公平性。

AQS

AQS(队列同步器),是用来构建锁或者其他同步组件的基础框架,它实现了同步状态的管理,线程的排队,等待与唤醒等底层操作。

  • 阻塞等待队列,共享/独占,公平/非公平,可重入,允许中断
    同步等待队列:AQS中的同步等待队列也叫CLH队列,是一种基于双向链表数据结构的队列,是FIFO先进先出线程等待队列,Java中的CLH队列是原CLH队列的一个变种,线程由原自旋机制改为阻塞机制。
    在这里插入图片描述
  • 条件等待队列:是一个多线程间协调通信的工具类,使得某个或者某些线程一起等待某个条件,只有当该条件具备时,这些等待线程才会被唤醒,从而重新争夺锁。
    在这里插入图片描述
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jzs1064

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值