线程的状态是线程的基本属性。在Java中,线程一共分为六种状态,它们分别是新建(NEW)、可运行(RUNNABLE)、阻塞(BLOCKED)、等待(WAITING)、调校时间的等待(TIMED_WAITING)和终止(TERMINATED)。本节将会简单介绍这六种状态,以及在程序中如何获取一个线程的当前状态等内容。
可以通过查阅Thread的源代码来了解Java中线程的一些状态:
上面截取的一段Thread源代码介绍了Thread的一些状态定义,其使用了enum(枚举)列举出了所有的状态,参考代码如下:
可以看出,在Java中,一共定义了六种线程的基本状态。
(1)新建(NEW):线程创建成果,但还没有调用start()方法启动。
(2)可运行(RUNNABLE):线程处于可执行的状态,表明该线程已经在Java虚拟机中执行,但可能它还在等待操作系统其他资源(如CPU等)。
(3)阻塞(BLOCKED):线程处于阻塞,其实是指该线程正在等待一个监控锁,特别是在多线程下的场景等待另一个线程同步块的释放。例如,出现线程synchronized多线程同步关键字修饰的同步块或方法中;或者之前调用了wait()方法,后来被notify()通知唤醒时重新进入synchronized多线程同步关键字修饰的同步块当中。
(4)等待(WAITING):线程处于等待状态,指的是该线程正在等待另一个线程执行某些特定的操作。例如,A线程调用了wait()方法,进入等待状态,实际上该线程可能是等待B线程调用notify()方法或notifyAII()方法;又或者是A线程使用了C线程的join()方法,所以按顺序在等待C线程的结束等。
(5)调校时间的等待(TIMED_WAITING):线程的这个状态与等待状态不同,这种是与时间相关的等待,一般是调用了某些设定等待时长参数的方法,导致该线程按该调校的时间进行等待。例如,sIeep(500)或wait(1000)等。
(6)终止(TERMINATED):线程执行完毕的状态。
这里已经简单介绍完Java线程的六种状态,读者可能一时间未能完全明白,但可以先大致记忆这六种状态。在后面的章节中,还会通过其他内容对这六种状态从侧面加以分析。
可以在程序中使用某个线程的getState()方法得到该线程目前这一刻的状态。实际上在多线程的环境下,一个线程的状态可能会在极短的时间内变化多次。下面先以一个简单的示例来看看一个线程的状态的变化,改写之前的ProgressBar01线程类的总的执行入口main()方法。
参考代码如下:
运行的参考结果如下:
通过这个简单的例子,我们可以看到,数数线程在非常短的时间内就发送了多次状态变化。例如,在刚创建好线程还没有启动时,数数线程的状态是NEW;当main线程立刻调用数数线程的start()方法时,数数线程的状态变成了RUNNABLE;当数数线程刚开始工作不久,数到某个数字时,即数数线程正在运行中时,其状态也是RUNNABLE;当数数线程的工作完毕后,数数线程的状态变为TERMINATED。
需要强调一点,Java的线程不能单独存在RUNNING这一个状态值,实际上运行中的Java线程,其状态与使用了start()方法之后的RUNNABLE状态相同。
对Java的线程运行情况的描述,除了获取状态的方法外,还有一个isAIive()方法可以获得线程的活动情况,可以用于判断一个线程是否还活动(存活)。该方法返回的值为true或faIse,并不返回线程当前状态,但可以作为一种线程的描述方法。适当修改上面的示例,加入isAIive()方法。
参考代码如下:
运行后的参考结果如下:
可以看出,线程的活动情况与线程的RUNNABLE状态基本一致,也是在线程start()方法启动后为true,当线程结束时,线程的活动情况变为faIse。