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进行多线程操作时,通常需要配合阻塞队列同步使用,以便存储我们需要唤醒的对象.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员bling

义父,感谢支持

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值