LockSupport.park()是否会释放锁资源吗


LockSupport.park()是否会释放锁资源吗,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。大家知道,我最近在招人,今天遇到个同学,他的源码看过一些,然后我就开始了AQS连环问。我:说说AQS的大致流程?他:AQS包含一个状态变量,一个同步队列……balabala……互斥锁balabala,共享锁balabala……我:AQS中除了同步队列,还有什么队列?他:还有个Condition,Condition中有个条件队列……我:条件队列和同步队列有什么区别?他:条件队列balabala,然后调用LockSupport.park()进入休眠,等待被唤醒,……,balabala咦,这时我灵感突发:LockSupport.park()和Thread.sleep()有什么区别?他:Thread.sleep()不会释放锁资源,……,balabala我:LockSupport.park()会释放锁资源吗?他:会吧。(估计和Object.wait()搞混淆了)我:会吗?会吗?会吗?他(羞涩地低下了头):彤哥,不知道,你的文章里没写。(这段我瞎写的哈^^)OK,今天我们就来看看LockSupport.park()到底会不会释放锁资源。首先,我们先来看看Thread.sleep()和Object.wait()的区别,这是一个烂大街的题目了,大家应该都能说上来两点。(1)Thread.sleep()不会释放占有的锁,Object.wait()会释放占有的锁;(2)Thread.sleep()必须传入时间,Object.wait()可传可不传,不传表示一直阻塞下去;(3)Thread.sleep()到时间了会自动唤醒,然后继续执行;(4)Object.wait()不带时间的,需要另一个线程使用Object.notify()唤醒;(5)Object.wait()带时间的,假如没有被notify,到时间了会自动唤醒,这时又分好两种情况,一是立即获取到了锁,线程自然会继续执行;二是没有立即获取锁,线程进入同步队列等待获取锁;其实,他们俩最大的区别就是Thread.sleep()不会释放锁资源,Object.wait()会释放锁资源。我们再来看看Thread.sleep()和Condition.await()的区别。其实,这个题目和上面的题目比较类似,因为本来Object.wait()和Condition.await()的原理就比较类似,可以参考之前彤哥写的《死磕 java线程系列之线程的生命周期》之篇文章。这个题目的回答思路跟Object.wait()是基本一致的,不同的是Condition.await()底层是调用LockSupport.park()来实现阻塞当前线程的。实际上,它在阻塞当前线程之前还干了两件事,一是把当前线程添加到条件队列中,二是“完全”释放锁,也就是让state状态变量变为0,然后才是调用LockSupport.park()阻塞当前线程,可以参考之前彤哥写的《死磕 java同步系列之ReentrantLock源码解析(二)——条件锁》这篇文章。看到这里,今天开篇提的那个问题是不是就有答案了呢【本文由公从号“彤哥读源码”原创】?LockSupport.park()还有几个兄弟方法——parkNanos()、parkUtil()等,我们这里说的park()方法统称这一类方法。(1)从功能上来说,Thread.sleep()和LockSupport.park()方法类似,都是阻塞当前线程的执行,且都不会释放当前线程占有的锁资源;(2)Thread.sleep()没法从外部唤醒,只能自己醒过来;(3)LockSupport.park()方法可以被另一个线程调用LockSupport.unpark()方法唤醒;(4)Thread.sleep()方法声明上抛出了InterruptedException中断异常,所以调用者需要捕获这个异常或者再抛出;(5)LockSupport.park()方法不需要捕获中断异常;(6)Thread.sleep()本身就是一个native方法;(7)LockSupport.park()底层是调用的Unsafe的native方法;二者都会阻塞当前线程的运行,他们有什么区别呢?经过上面的分析相信你一定很清楚了,真的吗?往下看!(1)Object.wait()方法需要在synchronized块中执行;(2)LockSupport.park()可以在任意地方执行;(3)Object.wait()方法声明抛出了中断异常,调用者需要捕获或者再抛出;(4)LockSupport.park()不需要捕获中断异常【本文由公从号“彤哥读源码”原创】;(5)Object.wait()不带超时的,需要另一个线程执行notify()来唤醒,但不一定继续执行后续内容;(6)LockSupport.park()不带超时的,需要另一个线程执行unpark()来唤醒,一定会继续执行后续内容;(7)如果在wait()之前执行了notify()会怎样?抛出IllegalMonitorStateException异常;(8)如果在park()之前执行了unpark()会怎样?线程不会被阻塞,直接跳过park(),继续执行后续内容;最后两点是不是没想到?!其实,在《死磕 java线程系列之自己动手写一个线程池(续)》这篇文章里代码注释里稍微提到过unpark()这个方法,它先执行,则后续的park()方法将不再起作用。park()/unpark()底层的原理是“二元信号量”,你可以把它相像成只有一个许可证的Semaphore,只不过这个信号量在重复执行unpark()的时候也不会再增加许可证,最多只有一个许可证。关于信号量的内容,可以参考《死磕 java同步系列之Semaphore源码解析》这篇文章。不会,它只负责阻塞当前线程,释放锁资源实际上是在Condition的await()方法中实现的。好了,上面我们交叉对比了Thread.sleep()、Object.wait()、Con 香港云主机dition.await()、LockSupport.park()的区别。让我们用一张思维导图结束今天的内容。看完上述内容是否对您有帮助呢?如果还想对相关知识有进一步的了解或阅读更多相关文章,请关注开发云行业资讯频道,感谢您对开发云的支持。

相关推荐: github进不去的解决办法是什么

本篇文章为大家展示了github进不去的解决办法是什么,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。先确定不是网络问题之后,找到下图路径中的文件:hosts 然后,以记事本方式打开hosts文件,在文件 香港云主机后面…

免责声明:本站发布的图片视频文字,以转载和分享为主,文章观点不代表本站立场,本站不承担相关法律责任;如果涉及侵权请联系邮箱:360163164@qq.com举报,并提供相关证据,经查实将立刻删除涉嫌侵权内容。

(0)
打赏 微信扫一扫 微信扫一扫
上一篇 10/05 20:49
下一篇 10/05 22:10

相关推荐