经典面试题-lock与synchronized异同点

lock vs synchronized

  • 语法层面
    • synchronized 是java关键字,源码在 jvm 中,也被成为java中的内置锁,用 c++ 语言实现
    • Lock 是接口,源码由 jdk 提供,用 java 语言实现
    • 使用 synchronized 时,退出同步代码块锁会自动释放,而使用 Lock 时,需要手动调用 unlock 方法释放锁(可以写try…finally…中释放锁)
  • 功能层面
    • 二者均属于悲观锁、都具备基本的互斥、同步、锁重入功能

      互斥:多个线程争抢同一把锁,只有一个线程能够成功
      同步:多个线程同时运行,当一个线程运行到某一行代码时,发现需要其他线程的结果,此时该线程就不能继续向下运行了,需要等待其他线程的结果,才能继续向下执行(synchronized可以通过wait,notify实现同步;lock 可以使用条件变量condition.await()释放锁(释放锁之后就进入了等待队列);condition.single()唤醒 (唤醒之后还是会到blocked queue来排队) 来实现同步)
      锁重入:持锁的线程能不能继续加第二道锁第三道锁,如果可以则是可重入锁(synchronized,lock 都是可重入锁,对同一个对象加多道锁)

    • Lock 提供了许多 synchronized 不具备的功能,例如获取等待状态、公平锁、可打断、可超时、多条件变量

      获取等待状态:比如互斥,一个线程获取到锁,其他线程阻塞,此时想知道那些线程被阻塞住了,synchronized 就不行,但是lock就可以;在比如同步时,有多个线程已经在对象上调用了wait()在等等,想知道该对象上有哪些线程在等待,synchronized 就不行,但是lock就可以;
      公平锁:多个线程争抢锁,失败的线程在次是先来先得还是允许别插队呢,先来先得则为公平锁,允许插队则是非公平锁;synchronized 只支持非公平锁(并不是根据锁后给等待的线程分配锁的。每次锁被释放后,任何一个线程都有机会竞争到锁。目的就是为了提高执行性能,当然缺点是有可能会产生线程饥饿。)Lock 即支持公平锁又支持非公平锁;公平锁的吞吐量上并不如非公平锁高,一般推荐非公平锁
      可打断:有一个持锁线程,我的线程想获取锁时,如果是lock则可以打断;synchronized 不支持打断
      可超时:lock支持设置超时时间,如果超时则放弃锁的获取;synchronized 不支持超时
      多条件变量:synchronized只有一个等待队列,lock有多个等待队列

    • Lock 有适合不同场景的实现,如 ReentrantLock(可重入锁), ReentrantReadWriteLock(适合读多写少的)
  • 性能层面
    • 在没有竞争时,synchronized 做了很多优化,如偏向锁、轻量级锁,性能不赖在
    • 竞争激烈时,Lock 的实现通常会提供更好的性能
TestReentrantLock类中打印的

| Lock ----------------------|
| owner[null] state[0]       |
| blocked queue              |
| waiting queue [c1]         |
| waiting queue [c2]         |
|----------------------------|
owner:代表锁的持有者,null表示没有线程持有这把锁,state代表加锁状态,0表示没有人对他加锁,如果有人加锁则加1
blocked queue:如果获取锁失败则进入队列等待;双向链表
waiting queue [c1]:当前线程获取锁之后条件不满足,则先把锁释放开,将锁给别人用,当前线程需要在waiting queue中等待;LOCK.newCondition("c1");来创建waiting queue;单向链表
  • 条件变量
    ReentrantLock 中的条件变量功能类似于普通 synchronized 的 wait,notify,用在当线程获得锁后,发现条件不满足时,临时等待的链表结构
    与 synchronized 的等待集合不同之处在于,ReentrantLock 中的条件变量可以有多个,可以实现更精细的等待、唤醒控制
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值