大厂面试题:ReentrantLock 与 synchronized异同点对比 - JavaBuild
source link: https://www.cnblogs.com/JavaBuild/p/18149963
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
在过去的博文中我们学习了ReentrantLock 与 synchronized这两种Java并发使用频率最高的同步锁,在很多大厂面试题中有个经典考题:
ReentrantLock 与 synchronized异同点对比!
今天我们针对这一考题来做一个尽可能全面的总结哈。
ReentrantLock 与 synchronized
ReentrantLock是一种独占式的可重入锁,位于java.util.concurrent.locks中,是Lock接口的默认实现类,底部的同步特性基于AQS实现,和synchronized关键字类似,但更灵活、功能更强大、也是目前实战中使用频率非常高的同步类。
synchronized 依赖于 JVM 而 ReentrantLock 依赖于 API
synchronized
是依赖于 JVM 实现的,虚拟机团队在 JDK1.6 为 synchronized 关键字进行了很多优化,但是这些优化都是在虚拟机层面实现的,并没有直接暴露给我们。
ReentrantLock
是 JDK 层面实现的(也就是 API 层面,需要 lock() 和 unlock() 方法配合 try/finally 语句块来完成),ReentrantLock 比 synchronized 增加了一些高级功能。
- ReentrantLock 是一个类,而 synchronized 是 Java 中的关键字;
- ReentrantLock 必须手动释放锁。通常需要在 finally 块中调用 unlock 方法以确保锁被正确释放;
- ReentrantLock可以指定是公平锁还是非公平锁。而synchronized只能是非公平锁。所谓的公平锁就是先等待的线程先获得锁;
- synchronized 会自动释放锁,当同步块执行完毕时,由 JVM 自动释放,不需要手动操作;
- ReentrantLock 可以实现多路选择通知(可以绑定多个 Condition),而 synchronized 只能通过 wait 和 notify/notifyAll 方法唤醒一个线程或者唤醒全部线程(单路通知);
- ReentrantLock提供了一种能够中断等待锁的线程的机制,通过 lock.lockInterruptibly() 来实现这个机制。也就是说正在等待的线程可以选择放弃等待,改为处理其他事情。而synchronized不具备这种特点。
- ReentrantLock: 通常提供更好的性能,特别是在高竞争环境下;
- synchronized: 在某些情况下,性能可能稍差一些,但随着 JDK 版本的升级,性能差距已经不大了。
【注】:Condition是 JDK1.5 之后才有的,它具有很好的灵活性,比如可以实现多路通知功能也就是在一个Lock对象中可以创建多个Condition实例(即对象监视器),线程对象可以注册在指定的Condition中,从而可以有选择性的进行线程通知,在调度线程上更加灵活,我们在后面的学习中会耽误聊一聊它!
虽然说JDK1.6后synchronized的性能有很大的提升了,但是相比较而言,两者之间仍然存在性能差别,我们通过一个小demo来测试一下。
public class Test { private static final int NUM_THREADS = 10; private static final int NUM_INCREMENTS = 1000000; private int count1 = 0; private int count2 = 0; private final ReentrantLock lock = new ReentrantLock(); private final Object syncLock = new Object(); public void increment1() { lock.lock(); try { count1++; } finally { lock.unlock(); } } public void increment2() { synchronized (syncLock) { count2++; } } public static void main(String[] args) throws InterruptedException { Test test = new Test(); // ReentrantLock性能测试 long startTime = System.nanoTime(); Thread[] threads = new Thread[NUM_THREADS]; for (int i = 0; i < NUM_THREADS; i++) { threads[i] = new Thread(() -> { for (int j = 0; j < NUM_INCREMENTS; j++) { test.increment1(); } }); threads[i].start(); } for (Thread thread : threads) { thread.join(); } long endTime = System.nanoTime(); System.out.println("ReentrantLock完成时间: " + (endTime - startTime) + " ns"); // synchronized性能测试 startTime = System.nanoTime(); for (int i = 0; i < NUM_THREADS; i++) { threads[i] = new Thread(() -> { for (int j = 0; j < NUM_INCREMENTS; j++) { test.increment2(); } }); threads[i].start(); } for (Thread thread : threads) { thread.join(); } endTime = System.nanoTime(); System.out.println("synchronized完成时间: " + (endTime - startTime) + " ns"); }}
我们采用10个线程,每个线程做加1000000操作,执行时间对比如下:
//1000000万数据量时ReentrantLock完成时间: 272427700 nssynchronized完成时间: 675759100 ns
//10000数据量时ReentrantLock完成时间: 52207600 nssynchronized完成时间: 11291600 ns
很明显在数据量比较大的时候,竞争激烈时,ReentrantLock的性能要比synchronized好很多,但在数据量较低的情况下,会呈现出不同的结果。
如果本篇博客对您有一定的帮助,大家记得留言+点赞+收藏呀。原创不易,转载请联系Build哥!
如果您想与Build哥的关系更近一步,还可以关注“JavaBuild888”,在这里除了看到《Java成长计划》系列博文,还有提升工作效率的小笔记、读书心得、大厂面经、人生感悟等等,欢迎您的加入!
Recommend
-
7
性能对比:ReentrantLock vs SynchronizedTable of Contents记一次并发相关的性能测试。 最近遇到高并发引起的性能问题,最终定位到的问题是 LinkedBlockingQueue 的性能不行,最终通过创建了多个 Queue...
-
10
深圳某小公司面试题:AQS是什么?公平锁和非公平锁?ReentrantLock?
-
9
深圳某小公司面试题:AQS是什么?公平锁和非公平锁?ReentrantLock?文章以纯面试的角度去讲解,所以有很多的细节是未曾铺垫的。 单纯通过一篇文章来想要在面试中答出AQS、公平锁&&非公平锁以及ReentrantLock的加解锁 流程是很难的,强烈建议...
-
13
浅谈并发:synchronized & ReentrantLock2021-02-17 • Otstar Lin • 日常水文章.jpgsynchronizedsynchronized 是 Java 中的一个关键字,是 Java 本地代码实现的同步、重量级锁。synchroni...
-
9
-
7
Java中synchronized与ReentrantLock性能对比 | XINDOO前两天逛博客的时候看到有个人写了一篇博客说ReentrantLock比synchronized慢,这就很违反我的认知了,详细看了他的博客和测试代码,发现了他测试的不严谨,并在评论中友好地指出了他的问题,结果他直接把博...
-
12
作者:Matt Maribojoc译者:前端小智来源:stackabuse有梦想,有干货,微信搜索 【大迁世界】 关注这个在凌晨还在刷碗的刷碗智。本文 GitHub
-
6
Java/.Net双平台核心,Jvm和CLR运行异同点 本...
-
2
1、最初的 synchronized 它默认对临界资源添加重量级锁,即使可能并不存在竞争,只要走到临界区通通给你加锁。 现在来回答问题: 1) 如果是低于 JDK 1.5,抱歉你没得选,只能先将就着用 synchronized 重量级锁
-
3
在之前的博文中,我们介绍了volatile关键字,Java中的锁以及锁的分类,今天我们花5分钟时间,一起学习一下另一个关键字:synchronized。 synchronized是什么? 首先synchronized是Java中的一...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK