面试:Java线程有哪几种状态,它们之间是如何切换的
状态概述
java.lang.Thread.State
的枚举里。for (Thread.State state : Thread.State.values()) {
System.out.println(state);
}
打印结果:
NEW
RUNNABLE
BLOCKED
WAITING
TIMED_WAITING
TERMINATED
New 初始化状态 Runnable 可执行状态,包含Ready状态和Running状态,当线程start()方法被调用,线程处于可被线程调度器选中执行的状态,就是Ready。待到被执行时就是Running状态。等获得CPU时间片后变为运行中状态Running。 Waiting 等待被唤醒 Timed waiting 等待一段时间后自动唤醒 Blocked 线程阻塞,等待锁 Terminated 线程结束
状态如何切换
状态切换图:
简单状态切换 NEW -> RUNNABLE -> TERMINATED
Thread t1 = new Thread(()->{
System.out.println("Thread go!");
try {
Thread.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
//NEW
System.out.println("执行new后状态 1::" + t1.getState());
t1.start();
//RUNNABLE
System.out.println("执行start后状态 2::" + t1.getState());
//等待线程执行完毕
t1.join();
//TERMINATED
System.out.println("执行join后的状态 3::" + t1.getState());
打印结果:
执行new后状态 1::NEW
执行start后状态 2::RUNNABLE
Thread go!
执行join后的状态 3::TERMINATED
WAITING & TIMED_WAITING
Thread t2 = new Thread(() -> {
LockSupport.park();
System.out.println("t2 run begin");
try {
//睡眠3s
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
t2.start();
//主线程睡眠1s
TimeUnit.SECONDS.sleep(1);
System.out.println("t2 park:" + t2.getState());//WAITING
//唤醒t2
LockSupport.unpark(t2);
//主线程睡眠1s:确认t2被叫醒
TimeUnit.SECONDS.sleep(1);
System.out.println("t2 unpark:" + t2.getState());//TIMED_WAITING1
Blocked
final Object o = new Object();
Thread t3 = new Thread(() -> {
synchronized (o) {
System.out.println("t3 start!");
}
});
Thread t4 = new Thread(() -> {
synchronized (o) {
try {
Thread.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("t4 start");
}
});
//t4 start拿到锁
t4.start();
//主线程睡一秒,保证t4已经拿到锁
Thread.sleep(1);
//t3 start竞争锁
t3.start();
Thread.sleep(1);
System.out.println("t3状态:" + t3.getState());//Blocked
总结
有道无术,术可成;有术无道,止于术
欢迎大家关注Java之道公众号
好文章,我在看❤️
评论