马士兵java架构师

您现在的位置是:java学习笔记 >

java学习笔记

java线程的状态及转换

2024-05-08 22:31:24java学习笔记 本文浏览次数:0 百度已收录

本 文 目 录

java线程的状态及转换
在Java中,线程的状态是多线程编程的核心概念之一。了解线程状态及其转换对于编写高效、健壮的多线程程序至关重要。本文将从线程状态的定义出发,详细解释Java线程的六种状态,并通过对比表格的形式展示它们之间的差异。接着,将介绍核心类与方法,探讨线程状态转换的使用场景,并提供两个代码案例以加深理解。

线程状态定义及转换

线程状态是线程在其生命周期中可能处于的不同阶段。Java定义了六种线程状态:

  1. 新建(New):线程对象被创建,尚未启动。
  2. 可运行(Runnable):线程对象可以运行,可能正在运行,也可能正在等待CPU时间片。
  3. 阻塞(Blocked):线程等待获取一个它需要的监视器锁。
  4. 等待(Waiting):线程等待另一个线程执行一个特定的操作,如调用wait()
  5. 超时等待(Timed Waiting):线程等待一个特定的时间量,如调用sleep()wait(long timeout)
  6. 终止(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() 可运行(可能)然后终止

通过上述案例和表格,我们可以看到线程状态的转换是多线程编程中一个非常关键的环节,它影响着程序的执行流程和性能。正确理解和使用线程状态对于开发复杂的多线程应用至关重要。