线程状态:
线程状态的分类:
线程状态是一个枚举类型:Thread.State
public class test1 {
public static void main(String[] args) throws InterruptedException {
for (Thread.State state : Thread.State.values()) {
System.out.println(state);
}
}
}
线程状态一共有这6种:
1.NEW:
安排了工作,还未开始行动。
Thread t=new Thread();
一个线程刚创建完,它处于NEW状态,当调用了t.start()后,线程就会从NEW转化为RUNNABLE
2.RUNNABLE:
可工作的,又可以分成正在工作中和即将开始工作。
2.1)线程正在cpu上执行。
2.2)线程随时都可以去cpu上执行(随叫随到)
3.TERMINATED:
工作完成了(内核中的线程已经结束了,但是Thread对象还存在)
当线程中的run()方法执行完毕,或者线程中出现了未捕获的异常导致run()方法提前结束,线程就会进入TERMINATED状态。这也是线程生命周期中最后一个状态(意味着线程已经完成任务或者任务因异常结束,不会再占有CPU资源来执行任务相关代码)
4.TIMED_WATING:
表示排队等着其他事情。指定时间的阻塞,线程的阻塞是有时间上限的
比如:当线程调用了Thread.sleep(time)方法时,线程就会进入TIMED_WATING状态(这是一种线程暂时不占用cpu资源,等待一定时间后再继续执行或者根据条件提前被唤醒的状态)
5.WATING:
表示排队等着其他事情。死等(没有超时时间的等待),需要依赖其他线程的操作来唤醒,自身不会因为时间流逝而自恢复执行(如果没有其他线程唤醒处于WATING状态的线程,该线程就会一直等待下去)
6.BLOCKED:
表示等待其他事情。(是一种特殊的阻塞,比较特殊,由于锁导致的阻塞)
观察线程的状态变化和转移:
前面我们提到的isAlive()方法,认为处于NEW和TERMINATED状态的线程是死的,返回false;反之,则反
1.观察NEW,RUNNABLE,TERMINATED的状态的变化。
public class test1 {
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(() -> {
for (int i = 0; i < 10000; i++) {
}
}, "李四");
System.out.println(t.getName() + ": " + t.getState());;
t.start();
while (t.isAlive()) {
System.out.println(t.getName() + ": " + t.getState());;
}
System.out.println(t.getName() + ": " + t.getState());;
}
}
运行结果:
线程处于NEW的状态是非常短暂的,很快就会转换为RUNNABLE状态,然后任务执行完毕后转化为TERMINATED。
2.观察WAITING 、 BLOCKED 、 TIMED_WAITING 状态的转换
先看TIMD_WATING状态的转换:
从NEW状态(刚开始创建线程的时候,非常短暂),再到RUNNABLE状态(就绪状态),当执行到sleep时,线程处于TIMED_WATING状态(有时间限制的等待),其实最后还有一个状态TERMINATED状态(线程执行完毕),因为此时线程执行结束时间大于循环的时间
再看WATING状态的转换:
从NEW状态(刚开始创建线程的时候,非常短暂),再到RUNNABLE状态(就绪状态),当执行到wait()时,线程处于WATING状态(没有时间限制的等待,死等),也不会有后面的线程状态了,因为一直在死等。
最后一个状态BLOCKED(后面提高,先观察) :
public class test1 {
public static void main(String[] args) throws InterruptedException {
Object lock=new Object();
Thread t1=new Thread(()->{//线程1获取了lock这把锁
synchronized (lock){
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"t1");
Thread t2=new Thread(()->{//线程2尝试获取相同的lock这把锁
synchronized (lock){
System.out.println("t2获取锁了");
}
},"t2");
t1.start();
Thread.sleep(1000);
t2.start();
for(int i=0;i<=3;i++) {
System.out.println("t2"+t2.getState());
}
}
}
-------------5秒后--------------
此时锁被t1占用,当t2线程要想获取这把锁,就会进入BLOCKED状态,只有当5s后t1释放了这把锁,t2才能获取。