MST
星途 面试题库

面试题:Java JVM 中线程状态有哪些及如何转换

请详细阐述 Java JVM 中线程具有哪些状态,并且说明线程在什么情况下会从一种状态转换到另一种状态。
24.6万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试

在Java JVM中,线程具有以下六种状态:

  1. 新建(New):当线程对象被创建但尚未启动时,线程处于新建状态。例如,Thread thread = new Thread();此时线程还未开始执行。
  2. 运行(Running):当调用start()方法后,线程进入运行状态,此时线程获取到CPU资源正在执行run()方法中的代码。
  3. 阻塞(Blocked)
    • 等待锁:当一个线程试图获取一个被其他线程持有的锁时,该线程会进入阻塞状态。例如,有两个线程A和B,A线程持有某个对象的锁并正在执行同步代码块,B线程此时也想进入该同步代码块,就会进入阻塞状态,直到A线程释放锁。
    • 等待I/O操作完成:如果线程在执行I/O操作(如读取文件、网络请求等),在操作完成之前,线程会进入阻塞状态,等待I/O操作结束。
  4. 等待(Waiting)
    • 调用Object.wait():当线程在一个对象上调用wait()方法时,该线程会释放它持有的对象锁,并进入等待状态,直到其他线程在同一个对象上调用notify()notifyAll()方法唤醒它。例如:
    synchronized (obj) {
        obj.wait();
    }
    
    • 调用Thread.join():如果一个线程A调用另一个线程B的join()方法,线程A会进入等待状态,直到线程B执行完毕。例如:
    Thread threadB = new Thread(() -> {
        // 线程B的代码
    });
    threadB.start();
    threadB.join();// 线程A调用join方法,进入等待状态
    
    • 调用LockSupport.park():使用LockSupport类的park()方法也会使线程进入等待状态,直到调用LockSupport.unpark(Thread thread)唤醒指定线程。
  5. 计时等待(Timed Waiting)
    • 调用Thread.sleep(long millis):线程会进入计时等待状态,在指定的毫秒数内暂停执行。例如Thread.sleep(1000);线程会暂停1秒。
    • 调用Object.wait(long timeout):与Object.wait()类似,但增加了超时时间,在指定的时间内如果没有被唤醒,线程会自动醒来。
    • 调用Thread.join(long millis):与Thread.join()类似,但增加了超时时间,如果在指定时间内被调用的线程没有执行完毕,调用线程也会自动醒来。
    • 调用LockSupport.parkNanos(long nanos)LockSupport.parkUntil(long deadline)parkNanos指定等待的纳秒数,parkUntil指定等待到某个绝对时间点。
  6. 终止(Terminated):当线程的run()方法执行完毕,或者因为异常等原因提前终止,线程就会进入终止状态。此时线程已经结束执行,不能再转换到其他状态。