您的位置首页生活百科

synchronized 和 lock 有什么区别?

synchronized 和 lock 有什么区别?

的有关信息介绍如下:

synchronized 和 lock 有什么区别?

如果在开发中,你需要对某个共享资源加锁,但是你希望在这个获取锁的过程中,最多只等5秒钟,如果超时了拿不到就算了,直接去执行降级逻辑。这时候,你应该怎么做?用原生的synchronized关键字可以吗?

不行的,synchronized只能死等,拿不到锁就会一直阻塞在那。

又或者,一个线程正在苦苦等待获取锁,但业务上突然发生了变化(比如用户取消了请求),你想中断这个线程的等待,让它别再干了。用synchronized可以响应这个中断吗?

同样也是不行的,它对外部的中断信号完全无动于衷。

这就是我们在高并发编程中经常遇到的痛点:synchronized作为 JVM 内置的锁,用起来确实简单,但它太死板了。出于灵活性的考虑,我们需要一种更可控、更具弹性的加锁和释放锁机制。

这也是为什么 Java 引入了今天要聊的:public interface Lock。哪怕到了Java 17,虽然 JVM 对 synchronized做了无数次底层的锁膨胀优化,但在遇到需要精细化控制并发的场景时,Lock依然是不可替代的利器。

作为 API 层面的锁,Lock把控制权交给了开发者。我们来看看它的几个核心特性,以及最简单的代码实现(通常我们都会使用它的经典实现类 ReentrantLock)。

和synchronized自动释放锁不同,Lock最大的特点就是:加了锁,就必须手动释放。所以代码结构永远是配合try-finally出现的。

这是Lock极大提升灵活性的地方。你可以尝试去拿锁,拿到就干活,拿不到就走人;或者像开头说的那样,最多等一段时间。

同时,这也是提升性能的一种机制,不会死等,白白浪费资源。

如果一个线程A在等待锁的过程中,被其他线程(比如主线程)调用了A线程的interrupt(),lockInterruptibly()会立刻抛出 InterruptedException,让你有机会终止当前任务,而不是变成一个永远挂起的僵尸线程。

这块不太容易理解,我们写一个完整的例子来协助理解这个知识点。

这段代码几个要点要说明一下:

顺带一提,synchronized 永远是非公平锁(大家涌入进来一起抢,谁抢到算谁的)。而 Lock 允许你选择是否要排队。虽然绝大多数时候为了吞吐量我们用非公平锁,但有些强顺序要求的业务,公平锁就派上用场了。

说说synchronized 和 Lock 的区别,这是一道经典的Java并发编程面试题,下面我把主要区别列成一个表格,方便你复习。

那如果面试官问你,两者应该如何选择呢? 怎么回答?

你可以简单的这么说,synchronized是粗粒度的,如果要细粒度的做控制,可以使用Lock。

如果场景很简单,只是简单的互斥,就用:

可以了,且锁会自动释放。

如果需要超时获取、响应中断、非阻塞尝试获取,或者需要Condition这样的机制,就可以考虑 Lock。

感谢您的阅读,希望这篇回答对你有帮助。