LockSupport使用场景及原理详解

bt365最快线路检测 📅 2025-08-03 10:08:20 👤 admin 👁️ 1897 ❤️ 812
LockSupport使用场景及原理详解

一.LockSupport是什么?

首先看一下官方文档:https://www.apiref.com/java11-zh

乍一看可能还是有些蒙蔽,这里简单的概括一下:

就是一个线程阻塞工具类,所有的方法都是静态的.

二.能干什么

LockSupport类中最常用的方法就是park()和unpark()方法,分别可以阻塞和唤醒线程(作用类似于wait/notify方法)

三.为什么要用这个?和(wait/notify,await/signal)有什么区别?

1.知识点回顾

在之前我们有两种方法可以让一个线程进行阻塞,唤醒,如下所示

2.使用wait/notify存在什么问题?

(1)必须配合Synchronized关键字进行使用,否则会报异常

如上代码,会报非法监视状态异常,那为什么会报这个异常呢?

这个和Synchronized的底层原理有关,详情请看下面的原理图,在执行wait和notify方法时,需要锁定一个对象监视器,这个对象监视器有自己的owner(指向锁的持有者),WaitSet(等待队列,被阻塞的线程就放到这个容器中)等等属性,如果不锁定这个对象,就不能确定在阻塞时所需要的容器等属性,所以在调用wait/notify方法时会先进行判断,没有的话直接抛出异常.

(2)必须先执行wait,notify才能生效,否则就会一致被阻塞.

如上代码,先执行notify方法,再执行wait(),则线程始终会处于阻塞状态.程序无法结束.

其原理是因为会把阻塞的线程放到一个容器中,notify的时候去容器中取,那么直接notify的时候容器中肯定是没有对象的,也就无法生效.

3.使用ReentrantLock的await()和signal()方法也是一样,必须配置lock()方法进行使用,否则会报监视器异常,同时必须先阻塞才能被唤醒

4.使用LockSupport有什么效果呢?

(1)可以直接进行使用,不需要配合其他关键词或方法

(2)即使先执行"唤醒"方法,再执行阻塞方法,线程依旧可以顺利执行

如上,上述代码依旧可以正常执行

四.原理是什么?

为什么LockSupport可以不管顺序却仍能执行成功?原因就在于原理不同

LockSupport引入了许可证的思想,当执行unpark()方法的时候会赋给指定对象一个许可证,执行park()方法的时候判断当前对象是否拥有许可证,没有则进行阻塞,直到其拥有一个许可证才放行,如果拥有则直接放行.放行后将该对象拥有的许可证置空.

LockSupport调用的是Unsafe的native方法

需要注意的是某个对象最多只能拥有1个许可证,这意味着即使我们多次执行unpark方法,在执行一次park方法后,该对象拥有的许可证即为0.

如上代码所示,程序并不会正常结束,而是会一直阻塞.

注意:

在使用LockSupport进行多线程操作时,通常需要配合阻塞队列同步使用,以便存储我们需要唤醒的对象.

相关推荐

《无畏契约》称号修改方法
365招聘

《无畏契约》称号修改方法

📅 07-30 👁️ 4575