JAVA synchronized和ReenTrantLock的性能区别

小编 930

JAVA synchronized和ReenTrantLock的性能区别:synchronized的性能要比ReentrantLock差20%-30%。但 synchronized因多线程应运而生,它的存在也大幅度简化了Java多线程的开发。而且自从Synchronized引入了偏向锁,轻量级锁(自旋锁)后,两者的性能就差不多了。

1.synchronized和ReenTrantLock的性能区别

在Synchronized优化以前,synchronized的性能确实要比ReentrantLock差20%-30%,但是自从Synchronized引入了偏向锁,轻量级锁(自旋锁)后,两者的性能就差不多了,在两种方法都可用的情况下,官方甚至建议使用synchronized。

简单来说,ReenTrantLock的实现是一种自旋锁,通过循环调用CAS操作来实现加锁。它的性能比较好也是因为避免了使线程进入内核态的阻塞状态。此外,ReentrantLock还具有一些synchronized不具备的独有能力:首先,ReentrantLock可以指定是公平锁还是非公平锁,而Synchronized只能是非公平锁;其次,ReentrantLock提供了一个Condition类,用来实现分组唤醒需要唤醒的线程们,而Synchronized只能随机唤醒一个线程,或者唤醒全部线程;再者,ReentrantLock提供了一种能够中断等待锁的线程的机制,也就是说正在等待的线程可以选择放弃等待,改为处理其他事情,一般通过lock.lockInterruptibly()来实现这个机制。

2.synchronized和ReenTrantLock的其它区别

(1)锁的实现区别:synchronized是关键字依赖JVM实现的,底层是通过monitor对象来完成。(monitorenter、monitorexit)ReenTrantLock是具体类java.util.concurrent.locks.Lock是JDK实现的,类似于操作系统控制实现和用户自己写代码实现。

(2)可重入性的区别:ReenTrantLock和synchronized使用的锁都是可重入的,两者都是同一个线程每进入一次,锁的计数器都自增1,所以等到锁的计数器下降为0时才能释放锁。

(3)使用方法的区别:synchronized由编译器加锁和释放,默认是非公平锁,ReenTrantLock手动加锁和释放锁。

(4)便利性的区别:synchronized更便利,它是由编译器保证加锁与释放,不会产生死锁。ReentrantLock是需要手动释放锁,所以为了避免忘记手工释放锁造成死锁,所以较好在finally中声明释放锁。

延伸阅读

JAVA中的自旋锁是什么

自旋锁是指线程在获取锁的时候,当前锁被其他线程占用还未释放,那么当前线程会进入循环(for循环,while循环),一直重复获取锁的状态,而不会进入挂起或者睡眠等状态。当锁被释放后,当前线程获取到该锁的执行权,则会跳出循环执行相关代码。

由于自旋锁只是在当前线程不停的执行循环体,不需要进行线程状态的切换,因此相应时间很快,但是随着线程数量的增加,效率则会显著降低,因为每个线程都需要消耗CPU性能。所以,如果线程竞争不是很激烈,且锁的持有时间不是很长,这种情况下可以使用自旋锁。

回复

我来回复
  • 暂无回复内容

注册PingCode 在线客服
站长微信
站长微信
电话联系

400-800-1024

工作日9:30-21:00在线

分享本页
返回顶部