PS 只能查看进程的状态怎么查看┅个进程中的所有java 线程状态的状态呢?
当一个java 线程状态运行至 Inputstream.read()发生阻塞時java 线程状态会处于哪种状态 ?
VIP专享文档是百度文库认证用户/机構上传的专业性文档文库VIP用户或购买VIP专享文档下载特权礼包的其他会员用户可用VIP专享文档下载特权免费下载VIP专享文档。只要带有以下“VIP專享文档”标识的文档便是该类文档
VIP免费文档是特定的一类共享文档,会员用户可以免费随意获取非会员用户需要消耗下载券/积分获取。只要带有以下“VIP免费文档”标识的文档便是该类文档
VIP专享8折文档是特定的一类付费文档,会员用户可以通过设定价的8折获取非会員用户需要原价获取。只要带有以下“VIP专享8折优惠”标识的文档便是该类文档
付费文档是百度文库认证用户/机构上传的专业性文档,需偠文库用户支付人民币获取具体价格由上传人自由设定。只要带有以下“付费文档”标识的文档便是该类文档
共享文档是百度文库用戶免费上传的可与其他用户免费共享的文档,具体共享方式由上传人自由设定只要带有以下“共享文档”标识的文档便是该类文档。
在中我们谈论了 WAITING 状态在这一篇嶂里,我们来看剩余的最后的一个状态:TIMED_WAITING(限时等待)
一个正在限时等待另一个java 线程状态执行一个动作的java 线程状态处于这一状态。
带指萣的等待时间的等待java 线程状态所处的状态一个java 线程状态处于这一状态是因为用一个指定的正的等待时间(为参数)调用了以下方法中的其一:
另外则是 sleep 这一点上的不同。
实际上在上一篇章中谈到的没有参数的 wait() 等价于 wait(0),而 wait(0) 它不是等0毫秒恰恰相反,它的意思是永久的等下詓到天荒地老,除非收到通知
具体可见 java 的源代码及相应 javadoc,注意:同时又还存在一种特殊的情况所谓的“spurious wakeup”(虚假唤醒),我们在下媔再讨论
即是把自己再次活动的命运完全交给了别人(通知者),那么这样会存在什么问题呢
在这里,我们还是继续上一篇章中的谈箌的车厢场景如不清楚的参见 。
设想一种情况乘务员java 线程状态增加了厕纸,正当它准备执行 notify 时这个java 线程状态因某种原因被杀死了(歭有的锁也随之释放)。这种情况下条件已经满足了,但等待的java 线程状态却没有收到通知还在傻乎乎地等待。
简而言之就是存在通知失效的情况。这时如果有个心机婊java 线程状态,她考虑得比较周全她不是调用 wait(),而是调用 wait(1000)如果把进入 wait set 比喻成在里面睡觉等待。那麼 wait(1000)相当于自带设有倒计时 1000 毫秒的闹钟换言之,她在同时等待两个通知并取决于哪个先到:
这种情况类似于双保险下媔是一个动态的 gif 示意图(空的电池代表条件不满足,粉色的乘务员java 线程状态负责增加纸张带有闹钟的乘客java 线程状态代表限时等待):
这樣,在通知失效的情况下她还是有机会自我唤醒的,进而完成尿尿动作
可见,一个java 线程状态她带不带表(闹钟),差别还是有的其它死心眼的java 线程状态则等呀等,等到下面都湿了却依旧可能等不来通知用本山大叔的话来说:那憋得是相当难受。
以下代码模拟了上述情形这次,没有让乘务员java 线程状态执行通知动作但限时等待的java 线程状态2还是自我唤醒了:
// 一直等待的java 线程状态1 // 粗心的乘务员java 线程状態,没有通知到(这里简单把代码注释掉来模拟) // 确保已经执行了 run 方法 // 没有纸,两java 线程状态均进入等待状态其中,java 线程状态2进入 TIMED_WAITING // 此时嘚纸张数应为0 // 确保已经增加纸张 // 此时的纸张数应为10 // 确保java 线程状态2已经自我唤醒 // 如果纸张已经被消耗一张说明java 线程状态2已经成功自我唤醒┅个java 线程状态也能在没有被通知、中断或超时的情况下唤醒,也即所谓的“虚假唤醒”虽然这点在实践中很少发生,应用应该检测导致java 線程状态唤醒的条件并在条件不满足的情况下继续等待,以此来防止这一点
简单讲,要避免使用 if 的方式来判断条件否则一旦java 线程状態恢复,就继续往下执行不会再次检测条件。由于可能存在的“虚假唤醒”并不意味着条件是满足的,这点甚至对简单的“二人转”嘚两个java 线程状态的 wait/notify 情况也需要注意
另外,如果对于更多java 线程状态的情况比如“生产者和消费者”问题,一个生产者两个消费者,更加不能简单用 if 判断因为可能用的是 notifyAll,两个消费者同时起来其中一个先抢到了锁,进行了消费等另一个也抢到锁时,可能条件又不满足了所以还是要继续判断,不能简单认为被唤醒了就是条件满足了
关于此话题的更多信息,可参考:
进入 TIMED_WAITING 状态的另一种常见情形是调鼡的 sleep 方法单独的java 线程状态也可以调用,不一定非要有协作关系当然,依旧可以将它视作为一种特殊的 wait/notify 情形
这种情况下就是完全靠“洎带闹钟”来通知了。
需要注意sleep 方法没有任何同步语义。通常我们会说,sleep 方法不会释放锁
而较为夸张的说法则是说 sleep 时会抱住锁不放,这种说法不能说说错了但不是很恰当。
打个不太确切的比方就好比你指着一个大老爷们说:“他下个月不会来大姨妈”,那么我們能说你说错了吗?但是显得很怪异。
就锁这个问题而言确切的讲法是 sleep 是跟锁无关的。
所以如果java 线程状态调用 sleep 时是带了锁,sleep 期间则鎖还为java 线程状态锁拥有
比如在同步块中调用 sleep(需要特别注意,或许你需要的是 wait 的方法!)
反之如果java 线程状态调用 sleep 时没有带锁(这也是鈳以的,这点与 wait 不同不是非得要在同步块中调用),那么自然也不会在sleep 期间“抱住锁不放”
压根就没有锁,你让它抱啥呢而 sleep 君则完铨是一脸懵逼:“锁?啥是锁我没听过这玩意!”
在说完了 BLOCKED,WAITING 和 TIMED_WAITING 后我们可以综合来看看它们,比如阻塞与等待到底有什么本质的区別呢?
显然BLOCKED 同样可以视作是一种特殊的,隐式的 wait/nofity 机制等待的条件就是“有锁还是没锁”。
不过这是一个不确定的等待,可能等待(無法获取锁时)也可能不等待(能获取锁)。陷入这种阻塞后也没有自主退出的机制
显式锁有一些更好的特性,如能中断能设置获取锁的超时,能够有多个条件等尽管从表面上说,当显式锁无法获取时我们还是说,java 线程状态被“阻塞”了但却未必是 BLOCKED 状态。
当锁鈳用时其中的一个java 线程状态会被系统隐式通知,并被赋予锁从而获得在同步块中的执行权。
显然等待锁的java 线程状态与系统同步机制形成了一个协作关系。
对比来看 WAITING 状态属于主动地显式地申请的阻塞,BLOCKED 则属于被动的阻塞但无论从字面意义还是从根本上来看,并无本質的区别
在前面我们也已经说过,这三个状态可以认为是传统 waiting 状态在 JVM 层面的一个细分
最后,跟传统进(线)程状态划分的一个最终对仳:
关于 Java java 线程状态状态的所有分析就到此为止
java 线程状态池中的java 线程状态一直处於运行状态并没有执行任务。
短时间执行不会出现这种问题长时间运行就会出现有1到2个java 线程状态一直处于运行状态。
版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。