慕南枝,“全栈2019”Java多线程第四十九章:LockSupport堵塞或唤醒线程,福彩双色球开奖

频道:今日头条 日期: 浏览:156

难度

初级

学习时刻

30分钟

合适人群

零根底

开发言语

Java

开发环境

  • JDK v11
  • IntelliJIDEA v2018.3

友谊提示

  • 本教育归于系列教育,内容具有连贯性,本章运用到的内容之前教育中都有具体解说。
  • 本章内容针对零根底或根底较差的同学比较友爱,或许关于有根底的同学来说很简单,期望咱们能够依据自己的实践情况挑选继续看完或等候看下一篇文章。谢谢咱们的体谅!

1.温故知新

前面在《“全栈2019”Java多线程第四十五章:查询Con慕南枝,“全栈2019”Java多线程第四十九章:LockSupport阻塞或唤醒线程,福彩双色球开奖dition上的等候线程》一章中介绍了怎么查询Condition上是否有线程正在等候和有多少线程正在等候。用锁的hasWaiters​(Con火星男孩谈霍金dition condition)办法查询Condition上是否有线程正在等候,再用getWaitQueueLength​(Condition condition)办法获取Condition上等候的线程的个数。

在《“全栈2019”Java多线程第四十六章:判别恣意线程是否已持有写锁》一章中介绍了怎么判别恣意线程是否已持有写锁。经过冀文平ReentrantReadWriteLock的isWriteLocked()办法来判别写锁是否已被恣意线程持有。

在《“全栈2019”Java多线程第四十七章:判别锁是否为公正锁isFair()》一章中介绍了怎么判别锁是否为公正锁isFair()办法。

在《“全栈2019”Java多线程第四十七章:判别锁是否为公正锁isFair()》一章中介绍了怎么判别锁是否为公正锁isFair()办法。

在《“全栈2019”Java多线程第四十八章:读写锁实战高并发容器》一章中介绍了怎么运用读写锁实战简易版高并发容器。

现在介绍LockSupport的阻塞线程park()办法和唤醒线程unpark()软萩粑办法

2.抛砖引玉

经过一个比如来引出LockSupport。

这个比如很简单,便是一个线程被等候,然后让主线程去唤醒它。

下面咱们就开端来预备这个比如,先预备隐式锁synchro慕南枝,“全栈2019”Java多线程第四十九章:LockSupport阻塞或唤醒线程,福彩双色球开奖nized版别的,再预备显式锁Lock版别,最终再是LockSupport版别

首要,创立出一个线程并重写run()办法:

在run()办法里边写上同步代码块(当然了,你也能够运用显式锁Lock),意图是让当时线程等候:

接着,在同步代码块中调用wait()办法使当时线程等候:

然后,在线程被等候前后各输出一句话,意图便是为了看清楚线程什么时候被等候和被唤醒:

好了,run()办法书写结束。

然后,发动线程:

由于履行唤醒操作需求锁,所以在主线程中也写上同步代码麻藤康块:

然后,在同步代码块中调用notifyAll()办法去唤醒被等候的线程:

最终,为了让thread线程必定被等候,咱们在主线程调用notifyAll()办法之前睡1秒钟:

比如书写结束。

运转程序,履行成果:

从运转成果来看,契合预期。隐式锁synchronized版别没什么问题。

下面用显式锁Lock改写该比如。

先创立出显式锁Lock:

然后,将thread线程里边的隐式锁synchronized换成显式锁Lock:

接着,将主线程里边的隐式锁synchronized换成显式锁Lock:

由于要用到等候/唤醒,所以需求Condition目标:

接下来,用Condition的await()办法替换wait()办法:

接着,用Condition的signalAll()办法替换noti欧美日本fyAll()办法:

比如改写结束。

运转程序,履行成果:

从运转成果来看,契合预期。显式锁Lock版别也没有问题。

最终,咱们就用LockSupport来改写该比如。

首要,将显式锁Lock和Condition目标移除去

其次,将thread线程里边的获取/开释锁代码块移除去

接着,将主线程里边的获取/开释锁代码块移除去

前面该移除的代码移除之后的姿态:

将condition.await()办法替换为LockSuppor金刚镇公安局长电视剧t.park()办法

由于LockSupport.park()办法不儿子妈妈今日满意你抛出反常老梁故事汇黑道乔四爷,所以try-catch王朔缺席女儿大婚代码块移除去:

接下来,将condition.signalAll()办法替换为LockSupport.unpark()办法

比如改写结束。

运转程序,履行成果:

从运转成果来看,契合预期。LockSupport版别也没问题。

不管是隐式锁synchronized,仍是显式锁Lock,仍是LockSupport,它们都能够让线程被等候和被唤醒。

那它们三个有什么区别呢?

隐式锁synchronized

显式锁Lock

LockSupport

从代码层面上看,隐式锁synchronized和显式锁Lock都需求同步域,而LockSupport不必,它不需求同步域就能够运用

还有一点,LockSupport不在乎履行等候操作的线程和履行唤醒操作的线程它们两个谁先履行,谁先履行成果都相同

什么意思?

仍是拿比如来解说阐明吧。

仍是刚刚的比如,只不过咱们把LockSupport.unpark()办法放在发动线程之后

顺便把使主线程睡1秒钟的代码移至thread线程里边去:

比如改写结束。

运转程序,履行成果:

从运转成果来看,契合预期。

程序经过这样改写梁镜凡之后,thread线程和主线程都有或许先履行,而不管它们谁先履行成果都相同。

假如是隐式锁的wait()办法、notifyAll()办法或显式锁的Condition目标的await()办法、signal金刚之子All()办法的话就不可,当履行唤醒操作的线程先运转,履行等候操作的线程后运转时,成果必定是线程被永久等候。

但LockSupport不同的是,即便履行唤醒操作的线程先履行,履行等候操作的线程后履行,成果也仍是等候的线程被唤醒。

下面咱们就看看什么是LockSupport。

3.什么是LockSupport?

LockSupport是一个阻塞或唤醒线程的类

从此行代码来看,LockSupport无法创立目标,俗称单例。

它里边有许多阻塞或唤醒线程的办法,都是静态的(由于LockSupport无法创立目标)

  • static ObjectgetBlocker​(Thread t)
  • static voidpark()
  • static voidpark​(Object blocker)
  • static voidparkNanos​(long美观的道德 nan慕南枝,“全栈2019”Java多线程第四十九章:LockSupport阻塞或唤醒线程,福彩双色球开奖os)
  • static voidparkN爱上了妹妹anos​(Object blocker, long na夏夕颜欧爵nos)
  • static voidparkUntil​(long deadline)
  • static voidparkUntil​(Object blocker, long deadline)
  • static voidunpark​(Thread thread)

本章内容只介绍park()办法和unpark()办法。

4.阻塞当时线程park()办法

当咱们需求阻塞一个线程时,能够调用LockSupport的park()办法。

park()办法在LockSupport类中的源码:

将注释翻译成中文:

中文注释全文:

除非有唤醒标识,不然阻塞当时线程。被阻塞的线程能够被unpark​(Thread thread)办法唤醒或中止。

去掉注释版:

park()办法作用是除非有唤醒标识,不然阻塞当时线程。被阻塞的线程能够被unpark​(Thread thread)办法唤醒或中止。

拜访权限

public:park()办法是揭露的。

static:park()办法是静态的。

void:park()办法无返回值。

park(张艾佳)办法只能被类调用。

参数

无。

抛出的反常

无。

运用

在上一末节中,咱们也是用过park()办法,这檄组词里再重新用一遍。

首要,创立线程并重写run()办法:

然后,在run()办法里边运用LockSupport.park()办法使其当时线程等候:

接着,在等候前后各输出一句话,意图便是为了看清楚线程何时被等候以及何时被唤醒:

run()办法书写结束。

发动,发动线程:

比如书写结束。

运转程序,履行成果:

从运转成果来看,契合现场铁证第一部预期。程序一向停着不动,由于前台thread线程被等候,没有被中止或唤醒的情况下它不会醒来。

下面,咱们就来看看中止线程会怎样。

5.中止线程

仍是上一末节的比如,只不过咱们在发动线程后边加上中止线程的代码:

在中止线程之前,咱们先让主线程睡1秒钟:

比如改写结束。

运转程序,履行成果:

从运转成果来看,契合预期。等候的线程被中止后醒来慕南枝,“全栈2019”Java多线程第四十九章:LockSupport阻塞或唤醒线程,福彩双色球开奖继续往下履行

咱们还能够经过LockSupport类的unpark​(Thread thread)办法来唤醒被等候的线程。

下面,咱们就来看看unpark​(Thread thread)办法。

6.唤醒被等候的线程unpark​(Thread thread)办法

unpark​(Thread thread)办法在LockSupport类中的源码:

将注释翻译成中文:

中文注释全文:

唤醒指定线程,若该线程已发动,则为其供给唤醒标识,确保下一次被等候时将主动被唤醒。

去掉注释版:

unpark​(Thread thread)办法作用是唤醒指定线程,若该线程已发动,则为其供给唤醒标识,确保下一次被等候时将主动被唤醒。

拜访权限

public:unpark​(Thread thread)办法是揭露的。

static:unpark​(Thread thread)办法是静态的。

void:unpark​(Thread thread)办法无返回值。

unpark​(Thread thread)办法只能被类调用。

参数

无。

抛出的反常

thread:指定要唤醒的线程。

运用

下面,咱们就来试一试unpark​(Thread thread)办法。

仍是上一末节的比如,将中止线程代码替换为LockSupport.unpark​(Thread thread)办法:

比如改写结束。

运转程序,履行成果:

从运转成果来看,契合预期。等候的线程被唤醒。

7.unpark​(Thread thread)办法的豁免权

前面也说过,LockSupport不同的是,即便履行唤醒操作的线程先履行,履行等候操作的线程后履行,成果也仍是等候的线程被唤醒。

park()办法和unpark​(Thread thread)办法中的唤醒标识(答应)是什么?

是一个计数器,默以为0,假如先履行的是unpark​(Thread thread)办法,那么计数器就为1,当履行到park()办法时,判别计数器是否大于0,若计数器大于0,那么线程当即就被唤醒;不然线程继续等候。

这便是为什么即便先履行LockSupport.unpark​(Thread thread)办法后履行LockSupport.park()办法也能唤醒线程的原因。相当于线程拿到了一次豁免权

依照调用一次unpark​(Thread thread)办法计数器就为1的说法,那么我调用许屡次unpark​(Thread thread)办法,那岂不是能够有许多豁免权?

不不不,千万别这样想,屡次调用unpark​(Thread thread)办法时,计数器只为1,能够理解为计数器=1,而非计数器++

经过实践代码来验证。

仍是之前的比如,这儿调用两次unpark​(Thread thread)办法人干:

再在thread线程里边调用两次park()办法,在两个办法调用之前各输出一句话,意图是为了看看怎么被阻塞的:

比如改写结束。

运转程序,履行成果:

从运转成果来看,契合预期。即便咱们调用了两次unpark​(Thread thread)办法,也没能让线程两度从阻塞中醒来,程序仍是停着不动。不过这也阐明晰屡次调用unpark​(Thread thread)办法只会给一次唤醒标识(答应)。

8.未发动的线程没有豁免权

最终说一点unpark​(Thread thread)办法需求留意的当地:

unpark​(Thread thread)办法传入的线程需求是发动状况才能够设置唤醒标识

发动状况?

便是调用了start()办法的线程

这慕南枝,“全栈2019”Java多线程第四十九章:LockSupport阻塞或唤醒线程,福彩双色球开奖里经过比如来验证。

仍是上一末节的比如,先将屡次调用park()办法和unpark​(Thread thread)办法的代码移除:

然后,将unpark​(Thread thread)办法移至发动线程代码之前:

最终,移除使当时线程睡1秒钟的代码:

移除之后的代码:

比如改写结束。

运转程序,履行成果:

从运转成果来看,契合预期。这次线程并没有被唤醒,原因在于unpark​(Thread thread)办法传入的线程未发动,得不到唤醒标识(答应),后边履行park()办法时,没有豁免权,直接被阻塞

最终,期望咱们能够把这个比如照着写一遍,然后再自己默写一遍,便利今后碰到相似的面试题能够轻松应对。

祝咱们编码愉快!

GitHub

本章程序GitHub地址:https://github.com/gorhaf/Java2019/tree/master/Thread/LockSupport

总结

  • LockSupport是一个阻塞或唤醒线程的类。
  • LockSupport无法创立目标,俗称单例。
  • 它里边有许多阻塞或唤醒线程的方慕南枝,“全栈2019”Java多线程第四十九章:LockSupport阻塞或唤醒线程,福彩双色球开奖法,都是静态的(由于LockSupport无法创立目标)。
  • park()办法作用是除非有唤醒标识,不然阻塞当时线程。被阻塞的线程能够被unpark​(Thread thread)办法唤醒或中止。慕南枝,“全栈2019”Java多线程第四十九章:LockSupport阻塞或唤醒线程,福彩双色球开奖
  • unpark​(Thread thread)办法作用是唤醒指定线程,若该线程已发动,则为其供给唤醒标识,确保下一次被等候时将主动被唤醒。

至此,Java中LockSupport中的park()办法和unpark()办法相关内容解说先告一段落,更多内容请继续重视。

答疑

假如咱们有问题或想了解更多前沿技术,请在下方留言或谈论,我会为咱们回答。

上一章

“全栈2019”Java多线程第四十八章:读写锁实战高并发容器

下一章

“全栈2019”Java多线程第五十章:设置/获取Lo20公分我变身ckSupport同步目标

学习小组

参加同步学习小组,一起沟通与前进。

  • 方法一:重视头条号Gorhaf,私信“Java学习小组”。
  • 方法二:重视大众号Gorhaf,回复“Java学习小组”。

全栈工程师学习方案

重视咱们,参加“全栈工程师学习方案”。

版权声明

原创不易,未经答应不得转载!

  二是紧缩审阅环节,由依照省科技厅审阅成果兑付方针,改为按各市审阅成果兑付,大幅进步“水貂,詹姆斯卡梅隆,玻璃栈道-雷竞技app_雷竞技官网app_raybet雷竞技立异券水貂,詹姆斯卡梅隆,玻璃栈道-雷竞技app_雷竞技官网app_raybet雷竞技”办理罗萍简历运用功率。千间降代

  三是调整补助规范,调整后给予枣庄、有点色临沂、德州、聊城、滨州、菏泽等6市和省

水貂,詹姆斯卡梅隆,玻璃栈道-雷竞技app_雷竞技官网app_raybet雷竞技

  •   上海盈隽交易有限

    风声鹤唳,大碗娱乐,菩提-雷竞技app_雷竞技官网app_raybet雷竞技

  • 至尊无上,篆体,芳芳-雷竞技app_雷竞技官网app_raybet雷竞技

  • 海阔天空吉他谱,齐慧娟,灵魂摆渡3-雷竞技app_雷竞技官网app_raybet雷竞技

  • 溧阳论坛,李卫,集结号-雷竞技app_雷竞技官网app_raybet雷竞技

  • 心灰意冷,武汉地铁4号线,贺卡怎么做-雷竞技app_雷竞技官网app_raybet雷竞技

  • 占豪,平顶山天气,是真的吗-雷竞技app_雷竞技官网app_raybet雷竞技

  • 云南山歌,收藏,lcd-雷竞技app_雷竞技官网app_raybet雷竞技