Lock和Synchronized的区别

Lock和Synchronized的区别

下面主要以可重入锁ReentrantLock为例。

两者相同点是:

  • 都实现了多线程同步和内存可见性语义。
  • 都是可重入锁。

两者不同点是:

  • 同步实现机制不同,synchronized是通过Java对象头锁标记和Monitor对象实现同步;而ReentrantLock则是通过CAS、AQS和LockSupport(用于阻塞和解除阻塞)实现同步。
  • 可见性实现机制不同,synchronized依赖JVM内存模型保证包含共享变量的多线程内存可见性;而ReentrantLock是通过AQS中的volatile state状态来保证包含共享变量的多线程内存可见性。
  • 使用方式不同,synchronized 可以修饰实例方法(锁住实例对象)、静态方法(锁住类对象)、代码块(显示指定锁对象);ReentrantLock 显示调用 tryLock 和 lock 方法,需要在 finally 块中释放锁。
  • 功能丰富程度不同,synchronized 不可设置等待时间、不可被中断(interrupted);ReentrantLock 提供有限时间等候锁(设置过期时间)、可中断锁(lockInterruptibly)、condition(提供 await、condition(提供 await、signal 等方法)等丰富功能。
  • 锁类型不同,synchronized只支持非公平锁;而ReentrantLock提供公平锁和非公平锁实现,当然,在大部分情况下,非公平锁是高效的选择,但可能产生饥饿现象。

在 synchronized 优化以前,它的性能是比 ReenTrantLock 差很多的,但是自从 synchronized 引入了偏向锁,轻量级锁(自旋锁)等后,两者的性能就差不多了,在两种方法都可用的情况下,官方甚至建议使用 synchronized。

为什么非公平锁吞吐量大于公平锁?

​ 公平锁最大的特点就是要排队等待唤醒,等待队列靠后的线程要等到靠前的都唤醒完才轮到,比如A、B、C在等待队列中,可能C在B被唤醒之前就可以执行完毕,非公平锁可以让C先执行,这样就省下了C等待和唤醒之间的性能消耗。非公平锁可以减少CPU的唤醒和阻塞次数

posted @ 2021-04-22 10:54  i%2  阅读(62)  评论(0)    收藏  举报