一、线程状态
Section titled “一、线程状态”6个状态定义:@see java.lang.Thread.State
- New:初始状态,线程刚创建,但未启动。
- Runnable:运行状态,线程正在运行;亦可以是可运行的线程状态,等待CPU调度。
- Blocked:阻塞状态,线程阻塞等待监视器锁定的线程状态,处于synchronized同步代码块或方法中被阻塞。
- Waiting:等待状态。下列不带超时的方式:
- Object.wait、Thread.join、LockSupport.park
- Timed Waiting:超时等待状态,线程等待其他线程的通知,超时后自动唤醒。
- Thread.sleep(long)、Object.wait(long)、Thread.join(long)、LockSupport.parkNanos、LockSupport.parkUntil
- Terminated:终止状态,线程正常完成执行或者出现异常。
1.1 状态切换图
Section titled “1.1 状态切换图”stateDiagram-v2
direction LR
state "New(新线程)" as N
state "Runnable(可运行状态)" as R
state "Blocked(阻塞状态)" as B
state "Waiting(等待状态)" as W
state "Timed Waiting(定时等待)" as TW
state "Terminated(终止)" as T
N --> R: 开始
R --> B: 等待锁
B --> R: 已拿到锁
R --> W: 等待其他线程的通知
W --> R: 收到通知,继续执行
R --> TW: 有超时时间的等待其他线程的通知
TW --> R: 等待超时、或者收到通知,继续执行
R --> T: 执行结束
1.2 示例
Section titled “1.2 示例”public static void main(String[] args) throws Exception { // 第一种状态切换 - 新建 -> 运行 -> 终止 System.out.println("#######第一种状态切换 - 新建 -> 运行 -> 终止################################"); Thread thread1 = new Thread(new Runnable() { @Override public void run() { System.out.println("thread1当前状态:" + Thread.currentThread().getState().toString()); System.out.println("thread1 执行了"); } }); System.out.println("没调用start方法,thread1当前状态:" + thread1.getState().toString()); thread1.start(); Thread.sleep(2000L); // 等待thread1执行结束,再看状态 System.out.println("等待两秒,再看thread1当前状态:" + thread1.getState().toString()); // thread1.start(); TODO 注意,线程终止之后,再进行调用,会抛出IllegalThreadStateException异常
System.out.println(); System.out.println("############第二种:新建 -> 运行 -> 等待 -> 运行 -> 终止(sleep方式)###########################"); Thread thread2 = new Thread(new Runnable() { @Override public void run() { try { // 将线程2移动到等待状态,1500后自动唤醒 Thread.sleep(1500); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("thread2当前状态:" + Thread.currentThread().getState().toString()); System.out.println("thread2 执行了"); } }); System.out.println("没调用start方法,thread2当前状态:" + thread2.getState().toString()); thread2.start(); System.out.println("调用start方法,thread2当前状态:" + thread2.getState().toString()); Thread.sleep(200L); // 等待200毫秒,再看状态 System.out.println("等待200毫秒,再看thread2当前状态:" + thread2.getState().toString()); Thread.sleep(3000L); // 再等待3秒,让thread2执行完毕,再看状态 System.out.println("等待3秒,再看thread2当前状态:" + thread2.getState().toString());
System.out.println(); System.out.println("############第三种:新建 -> 运行 -> 阻塞 -> 运行 -> 终止###########################"); Thread thread3 = new Thread(new Runnable() { @Override public void run() { synchronized (DemoThread.class) { System.out.println("thread3当前状态:" + Thread.currentThread().getState().toString()); System.out.println("thread3 执行了"); } } }); synchronized (DemoThread.class) { System.out.println("没调用start方法,thread3当前状态:" + thread3.getState().toString()); thread3.start(); System.out.println("调用start方法,thread3当前状态:" + thread3.getState().toString()); Thread.sleep(200L); // 等待200毫秒,再看状态 System.out.println("等待200毫秒,再看thread3当前状态:" + thread3.getState().toString()); } Thread.sleep(3000L); // 再等待3秒,让thread3执行完毕,再看状态 System.out.println("等待3秒,让thread3抢到锁,再看thread3当前状态:" + thread2.getState().toString());}// 执行结果:
// #######第一种状态切换 - 新建 -> 运行 -> 终止################################// 没调用start方法,thread1当前状态:NEW// thread1当前状态:RUNNABLE// thread1 执行了// 等待两秒,再看thread1当前状态:TERMINATED
// ############第二种:新建 -> 运行 -> 等待 -> 运行 -> 终止(sleep方式)###########################// 没调用start方法,thread2当前状态:NEW// 调用start方法,thread2当前状态:RUNNABLE// 等待200毫秒,再看thread2当前状态:TIMED_WAITING// thread2当前状态:RUNNABLE// thread2 执行了// 等待3秒,再看thread2当前状态:TERMINATED
// ############第三种:新建 -> 运行 -> 阻塞 -> 运行 -> 终止###########################// 没调用start方法,thread3当前状态:NEW// 调用start方法,thread3当前状态:RUNNABLE// 等待200毫秒,再看thread3当前状态:BLOCKED// thread3当前状态:RUNNABLE// thread3 执行了// 等待3秒,让thread3抢到锁,再看thread3当前状态:TERMINATED