【并发编程】 --- 从五个维度对比synchronized关键字和Lock


维度1 — 从原始构成上来说

  • synchronized是关键字,属于JVM层面
  • Lock是具体类(java.util.concurrent.Locks.Lock)是api层面的锁

维度2 — 从使用方法上来说

  • synchronized不需要用户手动去释放锁,当synchronized代码执行完后系统会自动让线程释放对锁的占用(当然如果发生异常也会释放锁)
  • Reentrantlock则需要用户去手动释放锁若没有主动释放锁,就有可能导致出现死锁现象。
    • 需要lock().unlock()方法配合try/finally语句块来完成 — 》我觉得这应该算是一个使用范式了。

维度3 — 从等待是否可中断上来说

  • synchronized不可中断,除非抛出异常或者正常运行完成
  • ReentrantLock可中断,方式有以下两种:
    • 设置超时方法tryLock(long timeout, TimeUnit unit)
    • lockInterruptibly()放代码块中,调用interrupt() 方法可中断

之前写过两篇文章,有兴趣的可以参考:
【并发编程】 — synchronized/ReentrantLock两大特性(可重入性和不可中断性)介绍
《【并发编程】 — Reentrantlock源码解析5:再探不可中断性 + 线程unpark后诡异的Thread.interrupted()判断


维度4 — 从加锁是否公平角度来说

  • synchronized非公平锁
  • ReentrantLock两者都可以,默认公平锁,构造方法可以传入boolean值,true为公平锁,false 为非公平锁

维度5 — 从线程间的通信来说

  • synchronized只能用notify和notifyAll随机唤醒一个或多个线程
  • ReentrantLock可以利用Condition实现精确唤醒

从使用+易于理解的角度,我其实建议使用Lock + Condition的组合,有兴趣的可以看一下我之前的两篇文章进行一下对比:
【并发编程】 — 线程间的通信wait、notify、notifyAll
【并发编程】 — Lock/Condition完成生产者消费者模式+ABCABC顺序打印问题

猜你喜欢

转载自blog.csdn.net/nrsc272420199/article/details/106041001