java多线程周期_新手学JAVA(十一)-多线程----线程的生命周期

新建和就绪状态

运行状态和阻塞状态

线程死亡

当1个线程被创建并启动以后,其实不是1开始就处于履行状态,已不是1直处于运行状态。线程也是有生命周期的,包括:创建(New)、就绪(Runnable)、阻塞(Blocked)、运行(Running)、死亡(Dead)5种状态。当线程运行时,也不可能1直霸占着CPU独自运行,而是1直在运行、就绪状态之间切换。

新建和就绪状态

当程序通过new创建1个线程时,这个线程就处于新建(New)状态了,不过这个时候该线程并没有表现出线程的任何特点,和其他的普通java对象1样,java虚拟机为其分配内存,并初始化其变量的值。

当线程对象调用了start()方法以后,该线程就进入了就绪状态,此时还不是运行状态,java虚拟机为其创建方法调用栈和程序计数器,此时的线程表示可以运行了,但是具体甚么时候运行,还需要等待jvm的调度。

有1个需要注意的地方,启动1个线程需要调用的是start()方法,而不是用run()来启动线程,如果直接调用run方法的话,系统会把线程当做1个普通的对象,run()方法也只是1个普通的方法。给大家举个栗子:

package lifecycle;

public class InvokeRun extends Thread{

private int i;

public void run(){

for(;i<100;i++){

System.out.println(Thread.currentThread().getName() + " " +i);

}

}

public static void main(String[] args){

for(int i=0;i<100;i++){

System.out.println(Thread.currentThread().getName() + " " +i);

if(i==20){

new InvokeRun().run();

new InvokeRun().run();

}

}

}

}

当启动线程的时候直接用run()方法,终究的结果是:全部程序的运行只有1个线程。程序编程了单线程的了。主要是由于,当你启动线程的时候,如果调用的start()方法,系统会把run()方法当做线程的履行体。直接调用run()方法的话,在run()方法返回之前其他线程没法并发运行。

只能对处于新建状态的线程调用start()方法,否则将引发IllegalThreadStateException异常

运行状态和阻塞状态

当1个就绪的线程取得CPU以后,就进入了运行状态,系统如果只有1个CPU的话,就会出现多个线程在同1个CPU上轮换的现象,1个CPU在任什么时候间只有1个线程在运行。如果有多个CPU的话,就会出现多个线程并行(parallel)履行;

1个线程不可能1直处于运行状态,除非这个线程在足够短的时间内就可以履行完成,否则的话,线程在履行的进程中都会被中断数次,目的是为了给其他的线程履行的机会,具体的需要斟酌后台的履行策略。

62a32537c4c5005e0430ded6fc5cc185.png

上图是线程的状态转换图,通过上图我们就能够了解到,线程是在甚么条件下进入到阻塞(Blocked)状态,又在甚么条件下进入到就绪(Runnable)状态;通过上图还可以了解到1点,线程其实不是直接从运行状态转到就绪状态的,除yield()方法。

线程死亡

线程会以下面3种方式结束,结束后就是死亡状态。

run()或call()方法履行完成,线程正常结束。

线程抛出1个未捕获的Exception或Error。

直接调用该线程的stop()方法来结束该线程—-该方法通常容易致使死锁,不推荐使用。

当线程死亡以后,其他的线程其实不受其影响,而结束。其他的子线程启动以后,它的地位和主线程是同等的,不受主线程的影响。

如何测试1个线程是不是已死亡?用线程对象的isAlive()方法来测,当线程处于就绪、运行、阻塞状态时,返回的结果是true,当线程处于死亡、新建状态时返回的是false。下面举1个对已死的线程调用start()方法的例子:

package startDead;

public class StartDead extends Thread {

private int i;

public void run(){

for(;i<100;i++){

System.out.println(getName()+" "+i);

}

}

/**

*@param args

*/

public static void main(String[] args) {

StartDead sd =new StartDead();

for(int i=0;i<300;i++){

System.out.println(Thread.currentThread().getName()+" "+i);

if(i==20){

sd.start();

System.out.println(sd.isAlive());

}

//当i>20的时候,线程肯定已启动过了,如果sd.isAlive()为假时,那就是死亡状态了;

if(i>20 && !sd.isAlive()){

//试图再次启动线程

sd.start();

}

}

}

}

对已死亡的线程调用start()方法,会抛出IllegalThreadStateException异常。

Exception in thread "main" java.lang.IllegalThreadStateException

at java.lang.Thread.start(Thread.java:595)

at startDead.StartDead.main(StartDead.java:27)

不要试图对已死亡的线程调用start()方法,死亡就是死亡,死亡的线程不会再次被当做线程的履行体。程序只能对处于新建状态的线程调用start()方法,对处于新建状态的线程两次调用start()也是毛病的,这都会引发IllegalThreadStateException异常

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值