线程得生命周期:
当线程被创建并且启动之后,并不是一启动就进入执行状态,也不是一直处于执行状态,在线程得生命周期中,他要经过创建(New),就绪(Runnable),运行(Running),阻塞(Blocked),和死亡(Dead)。线程启动以后,不能一直霸占CPU独自运行,CPU需 要在多条线程之间切换,线程状态也会多次在运行,阻塞之间切换。
新建状态:new关键字创建一个线程后,该线程就处于新建状态,此时它和其他的java对象一样,仅仅由java虚拟机为其分配内存,并初始化其成员变量,此时线程对象没有表现任何线程的动态特征,程序也不会执行线程的执行体。
就绪状态:当线程调用了start()方法之后,该线程处于就绪状态,表示该线程可以运行了,但是并没有开始运行,何时运行取决于jvm里线程调度器的调度。
public class Thread4 extends Thread{ public void run() { for(int i = 0 ; i < 30 ; i++) { System.out.println(Thread.currentThread().getName() + "--" + i); } } public static void main(String[] args) { new Thread4().run(); new Thread4().run(); } }
注意: 启动线程是调用对象的start()方法 , 而不是直接调用run()方法,否则就变成单线程了
只能对处于新建状态的线程调用start()方法,否则将引起IllegalThreadStateException异常
运行状态: 处于就绪状态的线程获得了CPU开始执行run()方法的线程执行体,该线程就处于运行状态。
线程不可能一直在运行状态(除非线程执行体足够短,瞬间执行完成),线程运行过程中需要被中断目的是使其他线程获得执行的机会。线程调度,取决于底层平台所采取的策略。
阻塞状态:
当发生如下情况时,线程进入阻塞状态:
线程调用sleep()方法,主动放弃所占用的处理器资源
线程调用了一个阻塞式的IO方法,在该方法返回前,该线程被阻塞
线程试图获得一个同步监视器,但是该监视器正在被其他线程所持有
线程在等待某个通知(notify)
程序调用了线程suspend()方法将该线程挂起,但是,这个方法容易造成死锁,应当尽量避免使用该方法
被阻塞线程的阻塞解除后,必须重新等待线程调度器再次调度它
针对上面几种情况,当发生如下特定的情况时可以解除上面的阻塞,让该线程重新进入就绪状态
调用sleep()方法的线程过了指定时间
线程调用的阻塞式IO方法已经返回
线程成功的获得了试图取得的同步监视器
线程正在等待某个通知时,其他线程发出了一个通知
处于挂起状态的线程调用了resume恢复方法
yield可以让运行状态的线程,转入就绪状态
线程死亡:线程会以如下三种方式结束, 结束后就处于死亡状态。
run()或者call()方法执行完成,线程正常结束
线程抛出一个没有被捕获的Exception或者Error
直接调用线程的stop()方法来结束该线程 --该方法容易导致死锁,通常不推荐使用。
当主线程结束,其他线程不会受到任何影响。一旦子线程启动起来之后,它拥有和主线程同样的地位,不会受到主线程的影响。
isAlive()方法: 就绪,运行,阻塞 返回true; 新建 , 死亡 , 返回false;