线程状态的详细解释
初始(NEW)
线程对象被创建,但尚未调用
start()方法。此时线程还未开始执行,只是作为一个对象存在于内存中。运行(RUNNABLE)
- 就绪(READY): 线程对象创建后,通过调用
start()方法启动。此时线程进入就绪状态,等待操作系统的调度,以获取CPU时间片。 - 运行中(RUNNING): 当就绪状态的线程获得CPU时间片时,开始执行程序代码,进入运行状态。
在Java中,由于就绪和运行状态的切换非常频繁,且难以准确区分,因此将两者统称为“运行(RUNNABLE)”状态。
- 就绪(READY): 线程对象创建后,通过调用
阻塞(BLOCKED)
线程尝试获取某个对象的锁(如通过
synchronized关键字),但锁已被其他线程持有。此时线程进入阻塞状态,直到锁被释放并成功获取。等待(WAITING)
线程通过调用
Object类的wait()方法或其他等待方法(如Condition的await()方法)进入等待状态。此时线程需要等待其他线程的通知(通过notify()或notifyAll()方法)或中断来唤醒。超时等待(TIMED_WAITING)
线程通过调用带有超时参数的等待方法(如
Thread.sleep(long millis)、Object.wait(long timeout)等)进入超时等待状态。此时线程在指定的时间内等待,如果超时时间到达或收到其他线程的通知,则线程会被唤醒。终止(TERMINATED)
线程执行完毕或由于异常等原因终止执行,进入终止状态。此时线程不再占用系统资源。
状态流转的细化
- 从初始(NEW)到运行(RUNNABLE): 调用
start()方法。 - 从运行(RUNNABLE)到阻塞(BLOCKED): 尝试获取锁失败。
- 从阻塞(BLOCKED)到运行(RUNNABLE): 成功获取锁。
- 从运行(RUNNABLE)到等待(WAITING): 调用
wait()等方法。 - 从等待(WAITING)到运行(RUNNABLE): 收到其他线程的通知或中断。
- 从运行(RUNNABLE)到超时等待(TIMED_WAITING): 调用带有超时参数的等待方法。
- 从超时等待(TIMED_WAITING)到运行(RUNNABLE): 超时时间到达或收到其他线程的通知。
- 从运行(RUNNABLE)到终止(TERMINATED): 线程执行完毕或异常终止。
关于RUNNING状态的缺失
如你所述,由于CPU时间片的分配和线程状态的频繁切换,很难准确区分线程是处于就绪状态还是运行状态。因此,Java将两者统称为“运行(RUNNABLE)”状态,以表示线程当前是可执行的,只要获得CPU时间片就能立即执行。
总结
了解线程的状态及其流转对于编写高效、可靠的并发程序至关重要。通过合理管理线程状态,可以确保程序的正确性和性能。