✅synchronized的重量级锁很慢,为什么还需要重量级锁?

✅synchronized的重量级锁很慢,为什么还需要重量级锁?

典型回答

✅synchronized的锁升级过程是怎样的?

这里提到过synchronized的锁升级过程,其中介绍了偏向锁、轻量级锁以及重量级锁,同时我们也提到过,重量级锁是一种效率比较低的锁,所以很多人说他很慢,所以他叫"重量级锁"。但是既然慢,为啥还要用重量级锁呢?

其实,这个问题有点搞错了synchronized的偏向锁、轻量级锁,和重量级锁之间的目的和原理。synchronized本身是一个重量级锁,然后为了让他有些并发不高的情况下不要这么重才引入的偏向锁和轻量级锁。


为什么本身是一个重量级锁?先说说啥是所谓的重量级锁。


重量级锁是指在多线程竞争激烈的情况下,synchronized锁膨胀为一种系统级别的锁机制。与偏向锁和轻量级锁不同,重量级锁会阻塞线程,并会在加锁和解锁过程中频繁地与操作系统交互。

确实,**重量级锁相比轻量级锁和偏向锁更慢,原因是重量级锁会引入线程的阻塞与唤醒。**阻塞和唤醒一个线程需要CPU从用户态切换到内核态,这涉及操作系统的调度,开销较大。

也就是说,当多个线程竞争同一锁时,重量级锁会导致其他线程阻塞,所以他慢,但是其实这种阻塞是有必要的。因为并发抢锁的时候,只有阻塞才能保证了线程对共享资源的安全访问,能够避免数据竞争和不一致性问题。

而且,在非常激烈竞争的场景下,轻量级锁的自旋会导致CPU资源浪费,重量级锁通过阻塞来避免这些资源浪费。对于任务较重的操作,重量级锁能提高系统稳定性,避免性能因频繁自旋而下降。

相信很多人看到这还是迷迷糊糊地,举个例子

你去食堂买煎饼果子,就只有一个窗口在卖,你去了之后,发现有人在排队了,那你是不是得排队?

这不就是重量级锁么,就是大家都想买煎饼果子,但是窗口只有一个,那为了解决这种并发冲突,就只有排队了。

那么,如果你去的时候,你发现前面没人,那你就不用排队了,就直接买就行了,这不就是针对重量级锁的所谓优化么。

也就是说,在并发比较高的时候,或者有激烈的所争抢的时候,必须要用重量级锁才行。(这里谈的是Java原生的关键字中,不考虑reentrantlock这种Java后来出来的类)