Java synchronized关键字与ReentrantLock区别

synchronized关键字与ReentrantLock区别

从以下几个方面阐述两者差异
1 应用场景:
synchronized: 不能显示的释放锁,使用不灵活。在某些需要灵活控制锁的获取和释放场景下不适用。
ReentrantLock: 可以通过 lock\tryLock、unlock等方便的对程序加锁以及释放锁,使用起来更灵活。
2、使用方式
synchronized:修饰普通方法、静态方法、代码块。
ReentrantLock:Lock接口的实现类,通过ReentrantLock实例对象的 lock和unlock方法加锁和释放锁。ReentrantLock实例方法 lock、unlock
3、实现原理
synchronized:通过对象头中的ObjectMonitor 监视器记录获取对象锁的线程。其他没有获得锁的线程会被阻塞。
ReentrantLock: 通过AQS队列来实现阻塞线程的记录,具备FIFO顺序性。condition队列来实现synchronized 锁的 挂起,condition记录着 condition.wait()的线程,通过condition.signal唤醒的线程会有condition加入AQS队尾,从而等待获取锁执行。
4、线程通信
synchronized: 由synchronized 实现原理可知,其是通过ObjectMonitor来实现重量级锁,通过Object的wait、notify/notifyAll 来实现线程通信。
ReentrantLock 则是通过AQS队列与Condition队列实现线程挂起以及线程阻塞。
唤醒顺序synchronized的notify会随机唤醒一个处于wait状态的线程,而ReentrantLock由于condition队列的存在,调用一次signal() 会从condition取出头节点放入AQS等待队列,因此唤醒具有顺序性,即先wait的线程先唤醒。
5、公平性
ReentrantLock 实现了公平锁和非公平锁,公平锁和非公平锁在源码中有两处差别
1)、非公平锁:当一个线程获取锁失败【已有线程获取锁】,加入双向链表【同步队列】之前会再次尝试获取锁,而公平锁不会
2)、在tryAcquire()获取锁时,非公平锁会再次尝试获得锁,而公平锁会判断队列里面是否有Node节点【阻塞等待获取锁的线程】,如果存在则不会再次尝试获得锁
Synchronized 的notify会随机唤醒一个处于wait状态的线程,也可以调用waitAll()唤醒所有等待的线程,但都是非公平的

​​​​

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值