您现在的位置是:java学习笔记 >
java学习笔记
java线程的状态及转换
本 文 目 录
在Java中,线程的状态是多线程编程的核心概念之一。了解线程状态及其转换对于编写高效、健壮的多线程程序至关重要。本文将从线程状态的定义出发,详细解释Java线程的六种状态,并通过对比表格的形式展示它们之间的差异。接着,将介绍核心类与方法,探讨线程状态转换的使用场景,并提供两个代码案例以加深理解。
线程状态定义及转换
线程状态是线程在其生命周期中可能处于的不同阶段。Java定义了六种线程状态:
- 新建(New):线程对象被创建,尚未启动。
- 可运行(Runnable):线程对象可以运行,可能正在运行,也可能正在等待CPU时间片。
- 阻塞(Blocked):线程等待获取一个它需要的监视器锁。
- 等待(Waiting):线程等待另一个线程执行一个特定的操作,如调用
wait()
。 - 超时等待(Timed Waiting):线程等待一个特定的时间量,如调用
sleep()
或wait(long timeout)
。 - 终止(Terminated):线程执行完毕或被中断。
线程状态之间的转换如下:
- 新建 -> 可运行:调用
start()
方法。 - 可运行 -> 阻塞:尝试获取一个已被其他线程持有的锁。
- 可运行 -> 等待:调用
wait()
方法。 - 可运行 -> 超时等待:调用
sleep(long millis)
或wait(long timeout)
。 - 阻塞 -> 可运行:获取到锁。
- 等待 -> 可运行:其他线程调用
notify()
或notifyAll()
。 - 超时等待 -> 可运行:等待时间结束。
核心类与方法
Java中控制线程状态的核心类是Thread
。以下是一些关键方法:
start()
:启动线程,线程状态从新建变为可运行。run()
:线程执行的主体方法。sleep(long millis)
:使当前线程暂停执行指定的毫秒数,进入超时等待状态。wait()
:导致当前线程等待,直到另一个线程调用notify()
或notifyAll()
。notify()
:唤醒在此对象监视器上等待的单个线程。notifyAll()
:唤醒在此对象监视器上等待的所有线程。join()
:等待线程终止。
使用场景
线程状态的转换在多线程同步、线程间通信、定时任务执行等场景中非常重要。例如,在生产者-消费者问题中,线程状态的转换确保了生产者不会在队列满时生产新的对象,消费者也不会在队列空时消费对象。
代码案例
以下是两个简单的代码案例,展示了线程状态的转换:
案例1:线程启动与终止
public class ThreadStateExample1 extends Thread {
public void run() {
System.out.println("Thread is running.");
}
public static void main(String[] args) {
ThreadStateExample1 thread = new ThreadStateExample1();
thread.start(); // 新建 -> 可运行
try {
thread.join(); // 等待线程终止
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Thread has terminated.");
}
}
案例2:线程等待与唤醒
public class ThreadStateExample2 extends Thread {
public synchronized void run() {
while (!Thread.currentThread().isInterrupted()) {
System.out.println("Thread is running.");
try {
wait(); // 可运行 -> 等待
} catch (InterruptedException e) {
break;
}
}
}
public static void main(String[] args) throws InterruptedException {
ThreadStateExample2 thread = new ThreadStateExample2();
thread.start(); // 新建 -> 可运行
Thread.sleep(1000); // 当前线程超时等待1秒
thread.notify(); // 唤醒等待的线程
}
}
线程状态转换表格
以下是线程状态转换的表格:
当前状态 | 导致转换的操作 | 新状态 |
---|---|---|
新建 | start() | 可运行 |
可运行 | wait() | 等待 |
可运行 | sleep(long) | 超时等待 |
可运行 | 获取锁失败 | 阻塞 |
阻塞 | 获取锁成功 | 可运行 |
等待 | notify() | 可运行 |
超时等待 | 等待时间结束 | 可运行 |
任何状态 | interrupt() | 可运行(可能)然后终止 |
通过上述案例和表格,我们可以看到线程状态的转换是多线程编程中一个非常关键的环节,它影响着程序的执行流程和性能。正确理解和使用线程状态对于开发复杂的多线程应用至关重要。