theme: jzman
这是我参与更文挑战的第22天,活动详情查看: 更文挑战。
紧接着前面的内容 《一文看懂线程的生命周期(一)》,全面解答文章一开始提出的问题。
三、问题解答
3.1TIME-WAITING
和WAITING
区别是什么?
WAITING
是死等,除非中断、产生异常,主动释放。TIME-WAITING
是超时的等,除了WAITING
的触发条件,还采取我不笨,我只等我想等的时间,过时不候的策略。
3.2BLOCKED
与*WAITING
状态区别是什么?
Java
官方 Thread.State 对BLOCKED
的定义是:
A thread that is blocked waiting for a monitor lock is in this state。
大致意思是该线程在等待监视器(Monitor
)锁定时被阻止,处于此状态。
对WAITING
的定义是:
A thread that is waiting indefinitely for another thread to perform a particular action is in this state.
大致意思是无限期等待另一个线程执行特定操作的线程处于此状态。
哈哈,是不是看了也很懵,我也是。因为官方只是解释了是什么,但是没有对比这这两者的区别。
BLOCKED
其实本身也是处于一种阻塞的状态,所以把它看作一种特殊的WAITING
也是可以的。简单的说,WAITING
代表当前线程正在等待一些工作,所以当前线程现在很空闲。BLOCKED
代表当前线程正忙于完成工作,但是另一个线程挡住了当前线程的路,所以当前线程现在很空闲。
也许你还是不明白,用个表说明一切。
| BLOCKED
| WAITING
| | ------------------------------------------------------------ | ------------------------------------------------------------ | | 当其它线程通知WAITING
状态的线程,WAITING
状态的线程会扭转到此状态;在未获得对象锁之前,该线程将长期处于此状态。 | 线程在同步代码块中使用#wait
、#join
方法会使本线程处于此状态,除非其它线程对同一对象调用#notify
、#notifyAll
方法。 | | 阻塞的是等待其它线程释放锁。 | 阻塞的是等待其它线程来通知。 | | 不可中断 | 可被中断 |
如果你还不能明白,那我只能放大招了,如下图。
图上,一共有两个线程争夺锁资源,线程1刚开始获取到锁资源,处于RUNNING
状态,然后执行了#wait
方法,处于WAITING
状态,线程2通过CPU
调度获得锁资源,处于RUNNING
状态,执行了一段时间后,线程2对同一对象调用#notify
方法,线程1收到通知,扭转状态为BLOCKED
,等待对象锁Monitor
释放。线程2执行完,释放锁,线程1获取到锁,状态变为RUNNING
。
3.3sleep
、wait
、join
、yield
几个函数执行对线程分别影响是什么?
再讲各自对线程的影响之前,我们必要先认识到线程之间竞争的资源不但有锁资源,还有CPU
资源。
| sleep
| wait
| join
| yield
| | ------------------------------------------------------ | ---------------------------- | ------------------------------------------------------------ | ------------------------------------------------------------ | | 使线程处于WAITING
状态 | 使线程处于WAITING
状态 | 使线程处于WAITING
状态 | 执行完成线程仍然处于RUNNING
状态(就绪态) | | 释放CPU
资源,不释放锁资源 | 释放CPU
、锁资源 | 释放CPU
、锁资源 | 释放CPU
资源,不释放锁资源 | | 超时完成后扭转为RUNNING
状态(就绪态) | 被通知后扭转为BLOCKED
状态 | 被通知后扭转为BLOCKED
状态 | 有可能从马上就能从RUNNING
状态(就绪态)变为RUNNING
状态(运行态) | | 线程方法 | Object方法 | Object方法 | 线程方法 | | 不必在同步代码块内执行 | 必须在同步代码块内执行 | 不必在同步代码块内执行 | 不必在同步代码块内执行 | | 阻塞线程,在一定程度上,使执行流程串行,达到同步的作用 | 阻塞线程,用于线程之间的通信 | 让当前线程等待执行#join
方法的线程结束,使执行流程串行,达到同步的作用 | 暂停线程,让同优先级的程序有执行的机会 |
注意: 主线程调用其它线程的#sleep
方法,只会让当前线程休眠。
哥佬倌,莫慌到走!觉好留个赞,探讨上评论。欢迎关注面试专栏面时莫慌 | Java并发编程,面试加薪不用愁。也欢迎关注我,一定做一个长更的好男人。