在了解线程状态的转换之前,我们先来认识一下 Thread 类和 Object 类里提供的有关线程的方法。
不释放线程占有的监视器,也就是不释放锁。进入 TIME_WAITING 阻塞状态。即阻塞一段时间。
将当前占有的内核线程,让步给其他等待调用的线程,如果没有其他等待的线程,那么这方法不让步。
只能在当前代码执行的线程上下文内部使用才有效果,yield 就是把 CPU 让给正在争用 CPU 的线程进行使用。如果最后没有了争用的线程,那么本身进行执行,如果两个线程同时让步,这个方法没效果。
停止一个线程,有可能抛出 ThreadDeath 异常。释放所占有的所有锁。这样会导致无法预测的异常发生。为什么?因为如果这个线程正在持有一个对象的锁,进行同步代码块的执行,如果突然结束线程,锁住的代码块会立刻解锁,会导致无法预测的结果。
启动一个线程
中断一个线程,被中断的线程会抛出 InterruptedException 异常。
中断的线程一般都是通过 wait()、sleep() 等阻塞方法进入阻塞态,然后通过 interrpet() 方法可以打断他们的阻塞态。 其实实现中断依靠是一个状态位,通过去轮询判断这个状态位来响应中断
wait()、sleep() 等阻塞方法一般都有一个检查型异常 InterruptedException。
挂起一个线程,挂起一个线程无法释放这个线程的锁。会导致后面需要获取锁线程阻塞。(现在已经废弃,不推荐使用)
恢复一个挂起的线程。(现在已经废弃,不推荐使用)
在当前线程中加入另一个线程,在新加入的线程没有执行完毕之前,当前线程无法继续执行。
// isAlive() Thread 的一个方法,用来判断当前线程是否正在运行
// 通过轮询一个状态标志位,来阻塞当前线程
// 下面是 jdk 实现 join 方法的核心代码
while (isAlive()) {
wait(0);
}
释放锁,阻塞当前线程的执行,将当前线程放到锁对应的 Monitor 对象的等待队列中
随机唤醒一个 Monitor 对象的等待队列中阻塞的线程。并不能有选择的唤醒阻塞的线程,而 ReentrantLock 配合 Condition 可以分组地选择性的唤醒阻塞的线程。
唤醒所有 Monitor 对象的等待队列中阻塞的线程。
这是我在一篇博客中看到的最好的一张描述线程之间状态转换的图,搬来给大家理解理解。
可以从上下两个部分的角度来看这张图,上面的阻塞状态是为了等待某个事件的发生,下面的阻塞状态是由于同步而产生的,也就是争抢锁带来的。
接下来我会写一篇从操作系统角度来理解线程是怎么工作的文章来帮助大家理解线程之间的状态转换。
参考博文链接 https://blog.csdn.net/linxdcn/article/details/72819817?locationNum=13&fps=1