一、线程状态转换图
二、新建和就绪状态
新建状态:当使用关键字new创建一个线程对象的时候,该线程就处于新建状态,跟其他对象一样,让jvm为其分配内存,初始化变量。没有任何的线程特征,不会执行线程体。
就绪状态:当线程对象调用start方法的时候,该线程就处于就绪状态了。jvm会为其创建方法调用栈和程序计算器,但不会立刻执行run方法,只是表示他可以运行,至于何时开始运行,取决于jvm里的线程调度器的调度。
注意:启动线程的正确方法是调用Thread的start(),而不是直接调用run(),否则就变成单线程程序了。调用了线程的run方法之后,线程已经不在处于新建状态了,不要再次调用线程对象的start()方法了。只能对处于新建状态的线程调用start(),否则引发IllegalThreadStateException。
三、运行和阻塞状态
如果处于就绪状态的线程获得了CPU,那么线程就开始执行run()方法的线程体,这时线程处于运行状态。为此,我们不能再次调用start(),不然会抛出异常的。
当一个线程开始运行后,不可能一直处于运行状态。线程需要被中断,以便让其他线程可以得到执行的机会。
进入阻塞状态的几种情形:
1. 线程调用sleep()方法表示主动放弃所占有的的CPU资源。
2. 线程调用了一个阻塞式IO方法,在方法返回之前,线程被阻塞。
3. 线程试图获取一个同步监视器,但是该对象正被其它的线程所占用。
4. 线程正等待通知(notify)
当正在执行的线程被被阻塞后,其它线程就有机会获得运行。如果线程的阻塞被解除了,线程会重新进入就绪状态而不是运行状态。看上面的图就一目了然了。然后等待线程调度器的调度。
从图可以看出运行状态除了可以转换为阻塞状态外,还可以进入就绪状态。线程进入就绪状态的条件是线程失去CPU资源或线程调用yield()方法。
四、线程死亡
线程死亡有三种方式:
1. 线程的run()或call()执行完成,线程正常结束。
2. 线程抛出一个未知的异常或错误
3. 直接调用线程的stop()方法——该方法容易导致死锁,通常不推荐使用。
注意:对于已经死亡的线程,不能再次调用start()方法。