一、线程的状态
线程的6种状态
线程运行状态图
代码示例
/**
* 示例2 - 多线程运行状态切换示例 <br/>
*/
public class Demo2 {
public static Thread thread1;
public static Demo2 obj;
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 (Demo2.class) {
System.out.println("thread3当前状态:" + Thread.currentThread().getState().toString());
System.out.println("thread3 执行了");
}
}
});
synchronized (Demo2.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当前状态:" + thread3.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
二、线程的终止
错误的线程终止 - stop()
/**
* 示例3 - 线程stop强制性中止,破坏线程安全的示例
*/
public class Demo3 {
public static void main(String[] args) throws InterruptedException {
StopThread thread = new StopThread();
thread.start();
// 休眠1秒,确保i变量自增成功
Thread.sleep(1000);
// 暂停线程
// thread.stop(); // 错误的终止
thread.interrupt(); // 正确终止
while (thread.isAlive()) {
// 确保线程已经终止
} // 输出结果
thread.print();
}
}
public class StopThread extends Thread {
private int i = 0, j = 0;
@Override
public void run() {
synchronized (this) {
// 增加同步锁,确保线程安全
++i;
try {
// 休眠10秒,模拟耗时操作
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
++j;
}
}
/** * 打印i和j */
public void print() {
System.out.println("i=" + i + " j=" + j);
}
}
错误的终止:
i=1 j=0
正确的终止:
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at cn.maxleader.multithreading.StopThread.run(StopThread.java:18)
i=1 j=1
正确的线程终止1 - interrupt()
正确的线程终止2 - 标志位
/** 通过状态位来判断 */
public class Demo4 extends Thread {
public volatile static boolean flag = true;
public static void main(String[] args) throws InterruptedException {
new Thread(() -> {
try {
while (flag) { // 判断是否运行
System.out.println("运行中");
Thread.sleep(1000L);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
// 3秒之后,将状态标志改为False,代表不继续运行
Thread.sleep(3000L);
flag = false;
System.out.println("程序运行结束");
}
}
控制台输出:
运行中
运行中
运行中
程序运行结束