线程状态转换

线程状态转换

1.新建

  创建后尚未启动即new了一个线程。

2.运行

  处于运行状态,也可能正在等待cpu的时间片,包含了操作系统的线程的running状态和ready状态。

3.阻塞

  等待获取一个排它锁,如果其他线程释放了锁就会结束这种状态。

4.无限期等待

  等待其他线程的显示唤醒,否则不会被分配cpu时间片。

进入方法 退出方法
没有设置Timeout的Object.wait()方法 Object.notify()或者Object.notifyAll();
没有设置Timeout的Thread.join()方法 等到被调用的线程执行完毕
LockSupport.park() LockSupport.unpark(Thread)

  LockSupport是JDK中比较底层的类,用来创建锁和其他同步工具类的基本线程阻塞元语。java锁的同步框架的核心AQS:AbstractQueuedSychronizer,就是调用LockSupport.park(),和LockSupport.unpark()实现线程的阻塞和唤醒。LockSupport很类似于二元信号量(只有一个许可证可以使用),如果这个许可证还没被占用,当前线程获取许可证并继续执行;如果许可证已经被占用,当前线程阻塞,等待获取许可。

public static void main(String[]args){
    LockSupport.park();
    System.out.println("block");
}

  运行该代码,主线程会一直处于阻塞状态,原因是许可证默认是被占用的,调用park()时,获取不到许可证,所以进入阻塞状态。

如下代码:先释放掉许可证,在获取许可,主线程能正常的终止。

public static void main(String[]args){
    Thread thread=Thread.currentThread();
    LockSupport.unpark(thread);//释放许可
    LockSupport.park();   //获取许可
    System.out.println("b");
}

  LockSuppot是不可重入的,并且LockSupport能够在阻塞状态下响应中断。

5.限期等待

  无需其他线程显示的唤醒,在一定的时间后会被系统自动唤醒。

  调用Thread.sleep()方法使线程进入限期等待状态,常常用一个线程进入睡眠状态来描述。

  调用Object.wait()方法使线程进入限期等待或者无限期等待,常用挂起一个线程来描述。

  睡眠和挂起是用来描述行为,而等待和阻塞是用来描述状态。

  阻塞和等待的区别是,阻塞是被动的,它在等待一个排它锁。而等待是主动的,通过调用Thread.sleep()和Object.wait()进入。

进入方法 退出方法
Thread.sleep()方法 时间结束
设置了Timeout的Object.wait()方法 时间结束/notify()/notifyAll()
设置了Timeout的Object.join()方法 时间结束/被调用的线程执行完毕
LockSupport.parkNanos()方法 LockSupport.unpark(Thread)
LockSupport.parkUntil()方法 LockSuppoort.unpark(Thread)

  LockSupport.parkNanos()阻塞当前进程,最长时间不超过nanos秒,返回条件在park()的基础上增加了超时返回。

  LockSupport.parkUntil(),阻塞当前线程,知道deadline时间。

6.死亡

  可能是线程结束任务后的正常死亡,也可能是产生了异常而结束。

原文地址:https://www.cnblogs.com/yjxyy/p/10686481.html