关于AQS(AbstractQueuedSynchronizer)与Condition协作的一种通俗解释

关于AQS(AbstractQueuedSynchronizer)与Condition协作的一种通俗解释

假设

Condition:等待室

AQS:一个需要叫号的办事窗口

线程:办事的人

线程执行:办事

一般过程

假设线程1(假设为n1)要去排队办事,在取号机取了个最后面的号,坐在大厅椅子上等着,看着还没到自己,就睡着了(acquireQueued方法)。轮到n1了,窗口看n1在睡觉,叫人把n1从椅子上喊醒,叫他赶快办事(release方法)。在n1办事过程中,此时n1告诉窗口这事我先办一半,我先去等待室1(假设为Condition实例c1)等着,当其他线程办事时提到了c1,我再来(开始await方法)。

情况1:于是窗口叫c1的管理员把n1领到了c1,给了个号,c1里没人,于是给了个1号(addConditionWaiter方法)。n1觉得还得一会,就又在c1内的椅子上睡着了(LockSupport.park方法)。此时有三种情况:

  • 该n2办事了,办事时窗口听到n2提到了c1,于是叫c1的管理员去喊人,要一个人就行。于是管理员拿着号单子,找了一个最先到c1的人——n1(开始signal方法)。此时n1还在c1的椅子上睡觉,于是c1的管理员给他取了号,并把n1从c1抬到大厅椅子上,此时n1还在睡梦中(transferForSignal方法)。
  • 此时n1在c1睡觉,但是有人(精神不正常)溜到c1中,打了n1一巴掌就跑了。这一巴掌把n1扇醒了(中断使park方法返回),以为该再去办事了,于是n1自己走出c1,到大厅排了号(transferAfterCancelledWait方法),去大厅的椅子上接着睡觉接着等。
  • 该n2办事了,办事时窗口听到n2提到了c1,于是叫c1的管理员去喊人,要一个人就行。于是管理员拿着号单子,找了一个最先到c1的人——n1。在管理员到c1之前,因为此时n1在c1睡觉,但有人(精神不正常)溜到c1中,打了n1一巴掌就跑了。这一巴掌把n1扇醒了(中断使park方法返回),此时正好管理员到了c1,看到n1醒了,把n1领到大厅,并给他排了号(中断导致执行方法transferAfterCancelledWait,但是与signal方法竞争失败)。然后n1在大厅的椅子上接着睡觉接着等(acquireQueued方法)。

情况2:于是窗口叫c1的管理员把n1领到了c1,给了个号,c1里有一个人n3,于是给了个2号(addConditionWaiter方法)。n1觉得还得一会,就又在c1内的椅子上睡着了(LockSupport.park方法)。此时:

  • 该n2办事了,办事时窗口听到n2提到了c1,于是叫c1的管理员去喊人,要一个人就行。于是管理员拿着号单子,找了一个最先到c1的人——n3(开始signal方法),两种情况:
    • 此时n3正在c1的椅子上睡觉,于是c1的管理员给他取了号,并把n3从c1抬到大厅椅子上(transferForSignal方法),此时n3还在睡梦中。管理员根本就没叫在c1椅子上睡觉的n1。
    • 管理员还没到c1的时候,n3正在c1睡觉,被一个人(精神不正常)扇了一巴掌,c3同样认为是有人叫他,于是早就出去c1去大厅取号等着了。管理员找不到c3了(执行transferForSignal中,与transferAfterCancelledWait竞争失败,返回false),于是找第二个人——n1,执行情况1一样的操作(doSignal方法内的do-while循环)。

目前n3或者n1已经在大厅的椅子上睡眠多时了(acquireQueued方法),假如轮到n1了,窗口看n1在睡觉,叫人把n1从椅子上喊醒,叫他赶快办事(release方法)。n1到窗口,问c1的管理员,是你给我排的队(检查interruptMode)?

  • 情况1:若n1被扇一巴掌后没有和管理员一起排号,管理员说并没有给n1排号,说明叫错了。因为那一巴掌,影响了n1的睡眠,n1在窗口大闹(抛出中断异常);
  • 情况2:若n1在睡梦中被管理员抬到大厅并排号,或者是n1被扇醒且管理员领着n1排号(那一巴掌扇的时机刚好),那么管理员说是我给你排的号。n1继续办事,但是他还是记住有人扇了他一巴掌(继续执行,但是自我中断设置了中断标志位)。
  • 43
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值