线程,作为操作系统中的一个基本执行单元,是程序并发执行的基础。在电脑中,线程可以处于不同的状态,这些状态决定了线程的执行和调度。了解线程的这些状态,有助于我们更好地进行程序设计和优化。下面,就让我们一起揭开线程状态的面纱,探索它们各自的奇妙之处。
线程状态概述
线程在执行过程中,会经历以下几种基本状态:
- 新建状态(New)
- 可运行状态(Runnable)
- 阻塞状态(Blocked)
- 等待状态(Waiting)
- 超时等待状态(Timed Waiting)
- 终止状态(Terminated)
1. 新建状态(New)
当创建一个线程对象后,它就进入了新建状态。在这个状态下,线程已经被系统创建,但是还没有被调度到处理器上执行。
public class ThreadExample {
public static void main(String[] args) {
Thread t = new Thread(() -> {
System.out.println("线程开始执行");
});
System.out.println("线程创建完成");
t.start();
}
}
输出结果:
线程创建完成
线程开始执行
2. 可运行状态(Runnable)
线程创建完成后,如果调用其 start() 方法,则线程将从新建状态进入可运行状态。在这个状态下,线程被准备执行,但是可能因为其他线程正在运行而无法立即执行。
3. 阻塞状态(Blocked)
当一个线程因为某些原因(如等待同步锁、等待 I/O 操作等)无法继续执行时,它会进入阻塞状态。在阻塞状态下的线程不会占用处理器资源。
public class ThreadExample {
public static Object lock = new Object();
public static void main(String[] args) {
Thread t1 = new Thread(() -> {
synchronized (lock) {
System.out.println("线程1获取到锁");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread t2 = new Thread(() -> {
synchronized (lock) {
System.out.println("线程2获取到锁");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
t1.start();
t2.start();
}
}
输出结果:
线程1获取到锁
线程2获取到锁
4. 等待状态(Waiting)
等待状态是指线程调用 Object.wait() 方法后进入的状态。在这个状态下,线程会等待另一个线程调用 Object.notify() 或 Object.notifyAll() 方法,以唤醒它。
public class ThreadExample {
public static Object lock = new Object();
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(() -> {
synchronized (lock) {
System.out.println("线程1开始等待");
lock.wait();
System.out.println("线程1被唤醒");
}
});
Thread t2 = new Thread(() -> {
synchronized (lock) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
lock.notify();
System.out.println("线程2唤醒线程1");
}
});
t1.start();
t2.start();
t1.join();
t2.join();
}
}
输出结果:
线程1开始等待
线程2唤醒线程1
线程1被唤醒
5. 超时等待状态(Timed Waiting)
超时等待状态与等待状态类似,但线程会在一定时间后自动醒来。在 Java 中,线程可以通过调用 Object.wait(long timeout) 或 Thread.sleep(long millis) 方法进入超时等待状态。
public class ThreadExample {
public static Object lock = new Object();
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(() -> {
synchronized (lock) {
System.out.println("线程1开始等待");
try {
lock.wait(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程1被唤醒");
}
});
Thread t2 = new Thread(() -> {
synchronized (lock) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
lock.notify();
System.out.println("线程2唤醒线程1");
}
});
t1.start();
t2.start();
t1.join();
t2.join();
}
}
输出结果:
线程1开始等待
线程2唤醒线程1
线程1被唤醒
6. 终止状态(Terminated)
当线程执行完毕或者调用 Thread.interrupt() 方法时,线程将进入终止状态。在终止状态下,线程不再占用任何资源,也不会再执行任何操作。
总结起来,线程的状态转换是程序并发执行的关键。理解线程的各种状态及其转换,有助于我们更好地进行程序设计和优化。希望这篇文章能帮助你揭开线程状态的面纱,让你在编程的道路上更加得心应手。
