并发-Lock和Synchronized区别

本文对比分析了Java中synchronized关键字与Lock接口的差异,包括它们的加锁层面、获锁方式、获锁失败处理、偏向与重入特性、队列机制及解锁操作等关键点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 1. 两者所处层面不同

  • synchronized是Java中的一个关键字,当我们调用它时会从在虚拟机指令层面加锁,关键字为monitorenter和monitorexit
  • Lock是Java中的一个接口,它有许多的实现类来为它提供各种功能,加锁的关键代码为大体为Lock和unLock;

å¨è¿éæå¥å¾çæè¿°
2、获锁方式

  • synchronized可对实例方法、静态方法和代码块加锁,相对应的,加锁前需要获得实例对象的锁或类对象的锁或指定对象的锁。说到底就是要先获得对象的监视器(即对象的锁)然后才能够进行相关操作;
  • Lock的使用离不开它的实现类AQS,而它的加锁并不是针对对象的,而是针对当前线程的,并且AQS中有一个原子类state来进行加锁次数的计数;


3、获锁失败

  • 使用关键字synchronized加锁的程序中,获锁失败的对象会被加入到一个虚拟的等待队列中被阻塞,直到锁被释放;1.6以后加入了自旋操作;
  • 使用Lock加锁的程序中,获锁失败的线程会被自动加入到AQS的等待队列中进行自旋,自旋的同时再尝试去获取锁,等到自旋到一定次数并且获锁操作未成功,线程就会被阻塞;


4、偏向或重入

  • synchronized中叫做偏向锁:当线程访问同步块时,会使用 CAS 将线程 ID 更新到锁对象的 Mark Word 中,如果更新成功则获得偏向锁,并且之后每次进入这个对象锁相关的同步块时都不需要再次获取锁了。
  • Lock中叫做重入锁:AQS的实现类ReentrantLock实现了重入的机制,即若线程a已经获得了锁,a再次请求锁时则会判断a是否持正有锁,然后会将原子值state+1来实现重入的计数操作

TODO:synchronized偏向锁吗,感觉是有锁升级?


5、Lock独有的队列

  • condition队列是AQS中的一个Lock的子接口的内部现类,它一般会和ReentrantLock一起使用来满足除了加锁和解锁以外的一些附加条件,比如对线程的分组和临界数量的判断(阻塞队列)

TODO:synchronized没有等待队列吗


6、解锁操作

  • Synchronized:不能指定解锁操作,执行完代码块的对象会自动
  • Lock:可调用ulock方法去释放锁比synchronized更灵活

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值