上期我们编写了一段代码,演示线程的TIME_WAITING
的状态转换,这次我们来编写一个新的代码,演示WAITING
的状态转换。
1、代码示例
代码实现:
public class ThreadStateDemo02 {
public static void main(String[] args) throws InterruptedException {
//定义一个对象,用来加锁和解锁
Object obj = new Object();
//定义一个内部线程
Thread thread1 = new Thread(() -> {
System.out.println("2.执行thread.start()之后,线程的状态:" + Thread.currentThread().getState());
synchronized (obj) {
try {
//thread1需要休眠100毫秒
Thread.sleep(100);
//thread1 100毫秒之后,通过wait()方法释放obj对象锁
obj.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("4.被object.notify()方法唤醒之后,线程的状态:" + Thread.currentThread().getState());
});
//获取start()之前的状态
System.out.println("1.通过new初始化一个线程,但是还没有start()之前,线程的状态:" + thread1.getState());
//启动线程,此时thread1还没开始执行,执行权仍在main主线程手里
thread1.start();
//main线程休眠150毫秒,从main主线程开始休眠那一刻起,cpu被thread1抢走并休眠100毫秒
Thread.sleep(150);
//因为thread1在第100毫秒进入wait等待状态,所以在main线程休眠150毫秒后肯定可以获取thread1的状态
System.out.println("3.执行object.wait()时,线程的状态:" + thread1.getState());
//声明另一个线程进行解锁
new Thread(() -> {
synchronized (obj) {
//唤醒等待的线程
obj.notify();
}
}).start();
//main线程休眠10毫秒等待thread1线程能够苏醒(main线程一旦开始休眠,cpu就会给刚被唤醒的thread1线程抢走执行之前等待以后的代码)
Thread.sleep(10);
//获取thread1运行结束之后的状态
System.out.println("5.线程执行完毕之后,线程的状态:" + thread1.getState() + "\n");
}
}
控制台输出:
1.通过new初始化一个线程,但是还没有start()之前,线程的状态:NEW
2.执行thread.start()之后,线程的状态:RUNNABLE
3.执行object.wait()时,线程的状态:WAITING
4.被object.notify()方法唤醒之后,线程的状态:RUNNABLE
5.线程执行完毕之后,线程的状态:TERMINATED
通过控制台输出我们可以看出程序的执行流程:
- 首先输出1,此时线程
thread1
只是通过new
初始化了,但还没start
,所以thread1
的状态为NEW
; - 然后通过
thread1.start()
启动线程,此时thread1
还没开始执行,执行权仍在main
主线程手里; - 接着
main
线程休眠150毫秒,从main
主线程开始休眠那一刻起,cpu被thread1
抢走输出2,此时thread1
的状态是:RUNNABLE
,并休眠100毫秒; - 因为
thread1
在第100毫秒进入wait
等待状态,所以在main
线程休眠150毫秒后肯定可以获取thread1
的状态,输出3,此时状态为:WAITING
; - 接着声明另一个线程通过
obj.notify()
唤醒了当时唯一在等待的线程thread1
,此时thread1
进入等待队列,变为就绪状态,准备竞争锁; - 然后
main
线程休眠10毫秒等待thread1
线程能够苏醒(main
线程一旦开始休眠,cpu就会给刚被唤醒的thread1
线程抢走执行之前等待以后的代码),输出4,此时thread1
的状态为:RUNNABLE
; - 最后程序输出5,
thread1
线程的状态为TERMINATED
;
至此,示例结束;