1.4isAlive()方法
方法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:\itsoft\jdk\bin\java -Didea.launcher.port=7534 "-Didea.launcher.bin.path=C:\itsoft\idea\IntelliJ IDEA 2016.3.3\bin" -Dfile.encoding=UTF-8 -classpath "C:\itsoft\jdk\jre\lib\charsets.jar;C:\itsoft\jdk\jre\lib\deploy.jar;C:\itsoft\jdk\jre\lib\ext\access-bridge-32.jar;C:\itsoft\jdk\jre\lib\ext\cldrdata.jar;C:\itsoft\jdk\jre\lib\ext\dnsns.jar;C:\itsoft\jdk\jre\lib\ext\jaccess.jar;C:\itsoft\jdk\jre\lib\ext\jfxrt.jar;C:\itsoft\jdk\jre\lib\ext\localedata.jar;C:\itsoft\jdk\jre\lib\ext\nashorn.jar;C:\itsoft\jdk\jre\lib\ext\sunec.jar;C:\itsoft\jdk\jre\lib\ext\sunjce_provider.jar;C:\itsoft\jdk\jre\lib\ext\sunmscapi.jar;C:\itsoft\jdk\jre\lib\ext\sunpkcs11.jar;C:\itsoft\jdk\jre\lib\ext\zipfs.jar;C:\itsoft\jdk\jre\lib\javaws.jar;C:\itsoft\jdk\jre\lib\jce.jar;C:\itsoft\jdk\jre\lib\jfr.jar;C:\itsoft\jdk\jre\lib\jfxswt.jar;C:\itsoft\jdk\jre\lib\jsse.jar;C:\itsoft\jdk\jre\lib\management-agent.jar;C:\itsoft\jdk\jre\lib\plugin.jar;C:\itsoft\jdk\jre\lib\resources.jar;C:\itsoft\jdk\jre\lib\rt.jar;C:\多线程核心技术\第一章\out\production\第一章;C:\itsoft\idea\IntelliJ IDEA 2016.3.3\lib\idea_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:\itsoft\jdk\bin\java -Didea.launcher.port=7535 "-Didea.launcher.bin.path=C:\itsoft\idea\IntelliJ IDEA 2016.3.3\bin" -Dfile.encoding=UTF-8 -classpath "C:\itsoft\jdk\jre\lib\charsets.jar;C:\itsoft\jdk\jre\lib\deploy.jar;C:\itsoft\jdk\jre\lib\ext\access-bridge-32.jar;C:\itsoft\jdk\jre\lib\ext\cldrdata.jar;C:\itsoft\jdk\jre\lib\ext\dnsns.jar;C:\itsoft\jdk\jre\lib\ext\jaccess.jar;C:\itsoft\jdk\jre\lib\ext\jfxrt.jar;C:\itsoft\jdk\jre\lib\ext\localedata.jar;C:\itsoft\jdk\jre\lib\ext\nashorn.jar;C:\itsoft\jdk\jre\lib\ext\sunec.jar;C:\itsoft\jdk\jre\lib\ext\sunjce_provider.jar;C:\itsoft\jdk\jre\lib\ext\sunmscapi.jar;C:\itsoft\jdk\jre\lib\ext\sunpkcs11.jar;C:\itsoft\jdk\jre\lib\ext\zipfs.jar;C:\itsoft\jdk\jre\lib\javaws.jar;C:\itsoft\jdk\jre\lib\jce.jar;C:\itsoft\jdk\jre\lib\jfr.jar;C:\itsoft\jdk\jre\lib\jfxswt.jar;C:\itsoft\jdk\jre\lib\jsse.jar;C:\itsoft\jdk\jre\lib\management-agent.jar;C:\itsoft\jdk\jre\lib\plugin.jar;C:\itsoft\jdk\jre\lib\resources.jar;C:\itsoft\jdk\jre\lib\rt.jar;C:\多线程核心技术\第一章\out\production\第一章;C:\itsoft\idea\IntelliJ IDEA 2016.3.3\lib\idea_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:\itsoft\jdk\bin\java -Didea.launcher.port=7536 "-Didea.launcher.bin.path=C:\itsoft\idea\IntelliJ IDEA 2016.3.3\bin" -Dfile.encoding=UTF-8 -classpath "C:\itsoft\jdk\jre\lib\charsets.jar;C:\itsoft\jdk\jre\lib\deploy.jar;C:\itsoft\jdk\jre\lib\ext\access-bridge-32.jar;C:\itsoft\jdk\jre\lib\ext\cldrdata.jar;C:\itsoft\jdk\jre\lib\ext\dnsns.jar;C:\itsoft\jdk\jre\lib\ext\jaccess.jar;C:\itsoft\jdk\jre\lib\ext\jfxrt.jar;C:\itsoft\jdk\jre\lib\ext\localedata.jar;C:\itsoft\jdk\jre\lib\ext\nashorn.jar;C:\itsoft\jdk\jre\lib\ext\sunec.jar;C:\itsoft\jdk\jre\lib\ext\sunjce_provider.jar;C:\itsoft\jdk\jre\lib\ext\sunmscapi.jar;C:\itsoft\jdk\jre\lib\ext\sunpkcs11.jar;C:\itsoft\jdk\jre\lib\ext\zipfs.jar;C:\itsoft\jdk\jre\lib\javaws.jar;C:\itsoft\jdk\jre\lib\jce.jar;C:\itsoft\jdk\jre\lib\jfr.jar;C:\itsoft\jdk\jre\lib\jfxswt.jar;C:\itsoft\jdk\jre\lib\jsse.jar;C:\itsoft\jdk\jre\lib\management-agent.jar;C:\itsoft\jdk\jre\lib\plugin.jar;C:\itsoft\jdk\jre\lib\resources.jar;C:\itsoft\jdk\jre\lib\rt.jar;C:\多线程核心技术\第一章\out\production\第一章;C:\itsoft\idea\IntelliJ IDEA 2016.3.3\lib\idea_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已经不再是存活状态。