在Java编程中,线程是并发编程的重要组成部分。在其生命周期中,线程会经历多种状态。理解这些状态有助于开发者更好地控制线程的执行与调度。Java中的线程主要有以下六种状态:新建(New)、就绪(Runnable)、 blocked(阻塞)、等待(Waiting)、超时等待(Timed Waiting)和终止(Terminated)。下面将逐一介绍这六种状态,并给出相应的代码示例。
1. 新建(New)
当一个线程对象被创建时,它处于新建状态。此时,线程并未开始执行。
class MyThread extends Thread {
@Override
public void run() {
System.out.println("线程正在运行");
}
}
public class ThreadState {
public static void main(String[] args) {
MyThread thread = new MyThread(); // 处于新建状态
System.out.println("线程状态: " + thread.getState());
}
}
2. 就绪(Runnable)
新建状态的线程在调用 start()
方法后,进入就绪状态。线程的状态在就绪时,表示线程可以被线程调度器选中进行运行。
class MyThread extends Thread {
@Override
public void run() {
System.out.println("线程正在运行");
}
}
public class ThreadState {
public static void main(String[] args) {
MyThread thread = new MyThread();
thread.start(); // 线程进入就绪状态
System.out.println("线程状态: " + thread.getState());
}
}
注意,尽管调用了 start()
方法,线程并不一定立即开始执行,因为线程的调度是由JVM和操作系统共同决定的。
3. 阻塞(Blocked)
当一个线程尝试获取一个已经被其他线程持有的锁时,它就会进入阻塞状态。
class Counter {
public synchronized void increment() {
// 模拟耗时操作
try { Thread.sleep(100); } catch (InterruptedException e) {}
}
}
public class ThreadState {
public static void main(String[] args) {
Counter counter = new Counter();
Runnable task = () -> {
synchronized (counter) {
counter.increment();
}
};
Thread thread1 = new Thread(task);
Thread thread2 = new Thread(task);
thread1.start();
thread2.start();
System.out.println("线程状态: " + thread2.getState()); // 可能是阻塞状态
}
}
4. 等待(Waiting)
线程进入等待状态时,指的是它在等待另一个线程执行某个特定的操作,例如通过调用 Object.wait()
或 Thread.join()
。
class WaitNotifyExample {
public static void main(String[] args) throws InterruptedException {
final Object lock = new Object();
Thread waiter = new Thread(() -> {
synchronized (lock) {
try {
lock.wait(); // 进入等待状态
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
waiter.start();
Thread.sleep(100); // 确保waiter线程进入等待状态
System.out.println("waiter线程状态: " + waiter.getState()); // 输出等待状态
}
}
5. 超时等待(Timed Waiting)
这个状态是等待状态的一个子集,线程会在指定的时间段内等待。可以通过 Thread.sleep(timeout)
或 Object.wait(timeout)
方法使线程超时等待。
class TimedWaiting {
public static void main(String[] args) throws InterruptedException {
Thread timedWaitThread = new Thread(() -> {
try {
Thread.sleep(2000); // 超时等待状态
} catch (InterruptedException e) {
e.printStackTrace();
}
});
timedWaitThread.start();
Thread.sleep(100); // 确保timedWaitThread进入超时等待状态
System.out.println("timedWaitThread线程状态: " + timedWaitThread.getState()); // 输出超时等待状态
}
}
6. 终止(Terminated)
线程执行完毕或被异常终止后进入终止状态。
class TerminatedExample extends Thread {
public void run() {
System.out.println("线程执行完毕");
}
}
public class ThreadState {
public static void main(String[] args) {
TerminatedExample thread = new TerminatedExample();
thread.start();
try {
thread.join(); // 等待线程执行完毕
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程状态: " + thread.getState()); // 线程terminated状态
}
}
总结
通过以上六种状态的介绍,我们可以看到线程的生命周期是一个复杂而又灵活的过程。正确理解这些状态对于高效的多线程编程至关重要。合理运用线程状态的转换,能够帮助开发者更好地管理并发任务,提高程序的性能和响应速度。