interview:简述synchronized与Lock的区别

类别synchronizedLock
存在层次Java的关键字,在jvm层面上Lock是一个接口而已
锁的释放1、以获取锁的线程执行完同步代码,释放锁 2、线程执行发生异常,jvm会让线程释放锁程序在finally释放锁
锁的获取假设a获得锁,b线程在等待,如果a阻塞,b会一直阻塞等待分情况而定,Lock有很多种获取锁的方式,大致可以获得锁,但是线程可以自己中断不等
锁状态无法判断可以判断
锁类型可重入,不可中断,非公平可重入,可以判断,可以公平,可以非公平
性能少量同步,如果太多线程并发,性能不如Lock适合并发高点的大量同步
为什么大量同步synchronized会性能这么低?

据我所知,synchronized原始采用的是CPU悲观锁机制,即线程获得的是独占锁。独占锁意味着其他线程只能依靠阻塞来等待线程释放锁。而在CPU转换线程阻塞时会引起线程上下文切换,当有很多线程竞争锁的时候,会引起CPU频繁的上下文切换导致效率很低。
而Lock用的是乐观锁方式。所谓乐观锁就是,每次不加锁而是假设没有冲突而去完成某项操作,如果因为冲突失败就重试,直到成功为止。乐观锁实现的机制就是CAS操作(Compare and Swap)。我们可以进一步研究ReentrantLock的源代码,会发现其中比较重要的获得锁的一个方法是compareAndSetState。这里其实就是调用的CPU提供的特殊指令。
现代的CPU提供了指令,可以自动更新共享数据,而且能够检测到其他线程的干扰,而 compareAndSet() 就用这些代替了锁定。这个算法称作非阻塞算法,意思是一个线程的失败或者挂起不应该影响其他线程的失败或挂起的算法。
有人做过测试

关于使用场景:

主要是根据上面表格里描述的两者的不同,比如并发量高点的选择lock,如果需要实现非公平的,可以synchronized,也可以lock

synchronized源码简单描述

我们都知道synchronized底层是通过monitor来实现同步
在Java虚拟机(HotSpot)中,monitor是由ObjectMonitor实现的(位于HotSpot虚拟机源码ObjectMonitor.hpp文件,C++实现的)。

ObjectMonitor中有几个关键属性:

_owner:指向持有ObjectMonitor对象的线程
_WaitSet:存放处于wait状态的线程队列
_EntryList:存放处于等待锁block状态的线程队列
_recursions:锁的重入次数
_count:用来记录该线程获取锁的次数

  • 线程T等待对象锁:_EntryList中加入T。
  • 线程T获取对象锁:_EntryList移除T,_owner置为T,计数器_count加1。
  • 线程T中锁对象调用wait():_owner置为null,计数器_count减1,_WaitSet中加入T等待被唤醒。
  • 持有对象锁的线程T执行完毕:复位变量的值,以便其他线程进入获取monitor。
    在这里插入图片描述

参考:这几篇讲synchronized原理都讲得挺好的,就是我现在好像还没消化掉… 先保存日后再看
【原创】Java并发编程系列07 | synchronized原理
【原创】Java并发编程系列08 | synchronized锁优化
【死磕Java并发】-----深入分析synchronized的实现原理

详解synchronized与Lock的区别与使用
美团文章:不可不说的Java“锁”事

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值