方法isAlive()的功能是判断当前线程是否处于活动状态
活动状态是线程已经启动且尚未终止,线程处于正在运行或准备开始运行的状态,就认为线程是存活的。
测试如下
1 package com.cky.thread; 2 3 /** 4 * Created by edison on 2017/11/28. 5 */ 6 public class MyThread9 extends Thread { 7 @Override 8 public void run() { 9 super.run(); 10 System.out.println("run="+this.isAlive()); 11 } 12 }
1 package com.cky.test; 2 3 import com.cky.thread.MyThread9; 4 5 /** 6 * Created by edison on 2017/11/28. 7 */ 8 public class Test14 { 9 public static void main(String[] args) throws InterruptedException { 10 MyThread9 th = new MyThread9(); 11 System.out.println("begin="+th.isAlive()); 12 th.start(); 13 // Thread.sleep(1000); 14 System.out.println("end="+th.isAlive()); 15 16 } 17 }
C:itsoftjdkinjava -Didea.launcher.port=7534 "-Didea.launcher.bin.path=C:itsoftideaIntelliJ IDEA 2016.3.3in" -Dfile.encoding=UTF-8 -classpath "C:itsoftjdkjrelibcharsets.jar;C:itsoftjdkjrelibdeploy.jar;C:itsoftjdkjrelibextaccess-bridge-32.jar;C:itsoftjdkjrelibextcldrdata.jar;C:itsoftjdkjrelibextdnsns.jar;C:itsoftjdkjrelibextjaccess.jar;C:itsoftjdkjrelibextjfxrt.jar;C:itsoftjdkjrelibextlocaledata.jar;C:itsoftjdkjrelibext ashorn.jar;C:itsoftjdkjrelibextsunec.jar;C:itsoftjdkjrelibextsunjce_provider.jar;C:itsoftjdkjrelibextsunmscapi.jar;C:itsoftjdkjrelibextsunpkcs11.jar;C:itsoftjdkjrelibextzipfs.jar;C:itsoftjdkjrelibjavaws.jar;C:itsoftjdkjrelibjce.jar;C:itsoftjdkjrelibjfr.jar;C:itsoftjdkjrelibjfxswt.jar;C:itsoftjdkjrelibjsse.jar;C:itsoftjdkjrelibmanagement-agent.jar;C:itsoftjdkjrelibplugin.jar;C:itsoftjdkjrelib esources.jar;C:itsoftjdkjrelib t.jar;C:多线程核心技术第一章outproduction第一章;C:itsoftideaIntelliJ IDEA 2016.3.3libidea_rt.jar" com.intellij.rt.execution.application.AppMain com.cky.test.Test14 begin=false end=true run=true Process finished with exit code 0
结果分析:上面刚开始还没有执行start()方法,所以begin为false,当开启线程之后,先打印end,说明此时cpu切换到了主线程,这时执行end,开启的线程还没有执行完毕,所以end为true,最后开启的线程
执行完run函数的代码就结束了。
下面更改代码如下
1 package com.cky.test; 2 3 import com.cky.thread.MyThread9; 4 5 /** 6 * Created by edison on 2017/11/28. 7 */ 8 public class Test14 { 9 public static void main(String[] args) throws InterruptedException { 10 MyThread9 th = new MyThread9(); 11 System.out.println("begin="+th.isAlive()); 12 th.start(); 13 Thread.sleep(1000); 14 System.out.println("end="+th.isAlive()); 15 16 } 17 }
1 C:itsoftjdkinjava -Didea.launcher.port=7535 "-Didea.launcher.bin.path=C:itsoftideaIntelliJ IDEA 2016.3.3in" -Dfile.encoding=UTF-8 -classpath "C:itsoftjdkjrelibcharsets.jar;C:itsoftjdkjrelibdeploy.jar;C:itsoftjdkjrelibextaccess-bridge-32.jar;C:itsoftjdkjrelibextcldrdata.jar;C:itsoftjdkjrelibextdnsns.jar;C:itsoftjdkjrelibextjaccess.jar;C:itsoftjdkjrelibextjfxrt.jar;C:itsoftjdkjrelibextlocaledata.jar;C:itsoftjdkjrelibext ashorn.jar;C:itsoftjdkjrelibextsunec.jar;C:itsoftjdkjrelibextsunjce_provider.jar;C:itsoftjdkjrelibextsunmscapi.jar;C:itsoftjdkjrelibextsunpkcs11.jar;C:itsoftjdkjrelibextzipfs.jar;C:itsoftjdkjrelibjavaws.jar;C:itsoftjdkjrelibjce.jar;C:itsoftjdkjrelibjfr.jar;C:itsoftjdkjrelibjfxswt.jar;C:itsoftjdkjrelibjsse.jar;C:itsoftjdkjrelibmanagement-agent.jar;C:itsoftjdkjrelibplugin.jar;C:itsoftjdkjrelib esources.jar;C:itsoftjdkjrelib t.jar;C:多线程核心技术第一章outproduction第一章;C:itsoftideaIntelliJ IDEA 2016.3.3libidea_rt.jar" com.intellij.rt.execution.application.AppMain com.cky.test.Test14 2 begin=false 3 run=true 4 end=false 5 6 Process finished with exit code 0
结果分析:上面执行start方法之后,调用了sleep方法,此时主线程被迫休眠,cpu切换到了子线程,这时执行完了run函数的代码,子线程已经关闭,这时cpu再切换回主线程,执行最后的end方法,但
此刻子线程已经关闭,不是存活状态。说明子线程在1秒内就执行完了。
在使用isAlive方法时,如果将线程对象以构造参数的方式传递给Thread对象进行start()启动,运行的结果是有差异的,造成这个差异的主要原因还是Thread.currentThread()和this的差异
测试代码如下
1 package com.cky.thread; 2 3 /** 4 * Created by edison on 2017/11/28. 5 */ 6 public class CountOperate2 extends Thread{ 7 public CountOperate2 () { 8 System.out.println("count 。。。 begin"); 9 System.out.println("thread name="+ Thread.currentThread().getName()); 10 System.out.println("thread current isalive="+ Thread.currentThread().isAlive()); 11 System.out.println("this.name="+ this.getName()); 12 System.out.println("this.isalive="+ this.isAlive()); 13 System.out.println("count ... end"); 14 } 15 16 @Override 17 public void run() { 18 super.run(); 19 System.out.println("run 。。。 begin"); 20 System.out.println("thread name="+ Thread.currentThread().getName()); 21 System.out.println("thread current isalive="+ Thread.currentThread().isAlive()); 22 System.out.println("this.name="+ this.getName()); 23 System.out.println("this.isalive="+ this.isAlive()); 24 System.out.println("run ... end"); 25 } 26 }
1 package com.cky.test; 2 3 import com.cky.thread.CountOperate2; 4 5 /** 6 * Created by edison on 2017/11/28. 7 */ 8 public class Test15 { 9 public static void main(String[] args) { 10 CountOperate2 cc = new CountOperate2(); 11 Thread t1 = new Thread(cc); 12 System.out.println("main begin t1 isalive="+t1.isAlive()); 13 t1.start(); 14 System.out.println("main end t1 isalive="+t1.isAlive()); 15 } 16 }
C:itsoftjdkinjava -Didea.launcher.port=7536 "-Didea.launcher.bin.path=C:itsoftideaIntelliJ IDEA 2016.3.3in" -Dfile.encoding=UTF-8 -classpath "C:itsoftjdkjrelibcharsets.jar;C:itsoftjdkjrelibdeploy.jar;C:itsoftjdkjrelibextaccess-bridge-32.jar;C:itsoftjdkjrelibextcldrdata.jar;C:itsoftjdkjrelibextdnsns.jar;C:itsoftjdkjrelibextjaccess.jar;C:itsoftjdkjrelibextjfxrt.jar;C:itsoftjdkjrelibextlocaledata.jar;C:itsoftjdkjrelibext ashorn.jar;C:itsoftjdkjrelibextsunec.jar;C:itsoftjdkjrelibextsunjce_provider.jar;C:itsoftjdkjrelibextsunmscapi.jar;C:itsoftjdkjrelibextsunpkcs11.jar;C:itsoftjdkjrelibextzipfs.jar;C:itsoftjdkjrelibjavaws.jar;C:itsoftjdkjrelibjce.jar;C:itsoftjdkjrelibjfr.jar;C:itsoftjdkjrelibjfxswt.jar;C:itsoftjdkjrelibjsse.jar;C:itsoftjdkjrelibmanagement-agent.jar;C:itsoftjdkjrelibplugin.jar;C:itsoftjdkjrelib esources.jar;C:itsoftjdkjrelib t.jar;C:多线程核心技术第一章outproduction第一章;C:itsoftideaIntelliJ IDEA 2016.3.3libidea_rt.jar" com.intellij.rt.execution.application.AppMain com.cky.test.Test15 count 。。。 begin thread name=main thread current isalive=true this.name=Thread-0 this.isalive=false count ... end main begin t1 isalive=false main end t1 isalive=true run 。。。 begin thread name=Thread-1 thread current isalive=true this.name=Thread-0 this.isalive=false run ... end Process finished with exit code 0
结果分析:
首先执行主函数的时候,实例化线程对象会执行构造函数,所以打印的Thread.currentThread().isAlive是true,但是这个这个线程对象还在实例化,并没有执行start()方法,所以this.isAlive为false,后面打印
t1也是false,之后执行了start()方法,子线程开启,cpu还是切换到了main线程,先执行main函数代码,打印t1为true,之后cpu切换到了子线程,执行run函数的代码,这时Thread.currentThread为true,但是this
却打印为false。个人理解为t1还是A还是存活的,但是由于他是由一个线程对象传递进去的,而里面的这个线程对象也就是thread-0已经不再是存活状态。