一 Thread.currentThread()与this
本文探讨Thread.currentThread()与this不一样的状况。
在将线程对象以结构参数的形式传递给Thread对象进行start()启动时,Thread.currentThread()与this的取值是不一样的。
代码:
package springboot.myrunable;
/**
- @author liuhongya328
*
*/
public class CountOperate extends Thread {
/** * 构造方法 */public CountOperate() { System.out.println("count-----begin"); System.out.println("Thread.currentThread().getName()=" + Thread.currentThread().getName()); System.out.println("Thread.currentThread().isAlive()=" + Thread.currentThread().isAlive()); System.out.println("this.getName()=" + this.getName()); System.out.println("this.isAlive()=" + this.isAlive()); System.out.println("count-----end");}@Overridepublic void run() { System.out.println("run-----begin"); System.out.println("Thread.currentThread().getName()=" + Thread.currentThread().getName()); System.out.println("Thread.currentThread().isAlive()=" + Thread.currentThread().isAlive()); System.out.println("this.getName()=" + this.getName()); System.out.println("this.isAlive()=" + this.isAlive()); System.out.println("run-----end");}
}
测试类:
package springboot.myrunable;
/**
- @author liuhongya328
*
*/
public class TestThread {
/** * @param args */public static void main(String[] args) { CountOperate cc = new CountOperate(); Thread t1 = new Thread(cc); System.out.println("main begin t1 isalive="+t1.isAlive()); t1.setName("A"); t1.start(); System.out.println("main end t1 isalive="+t1.isAlive());}
}
运行后果:
count-----begin
Thread.currentThread().getName()=main
Thread.currentThread().isAlive()=true
this.getName()=Thread-0
this.isAlive()=false
count-----end
main begin t1 isalive=false
main end t1 isalive=true
run-----begin
Thread.currentThread().getName()=A
Thread.currentThread().isAlive()=true
this.getName()=Thread-0
this.isAlive()=false
run-----end
阐明:
1.先看Test类
public static void main(String[] args) {
//main函数过程开始-name为main
//创立了一个cc的线程,线程为新建状态。线程名为Thread0CountOperate cc = new CountOperate();//创立了一个t1的线程,线程为新建状态。线程名为Thread1Thread t1 = new Thread(cc);System.out.println("main begin t1 isalive="+t1.isAlive());//将Thread1的名字改为At1.setName("A");//Thread1(A)启动,线程状态变为就绪t1.start();System.out.println("main end t1 isalive="+t1.isAlive());
}
2.再看实现类
/**
* 构造方法 */public CountOperate() { System.out.println("count-----begin"); //构造方法是main办法在执行 System.out.println("Thread.currentThread().getName()=" + Thread.currentThread().getName()); System.out.println("Thread.currentThread().isAlive()=" + Thread.currentThread().isAlive()); //以后线程的name,在new CountOperate()的时候曾经创立了cc线程,name为Thread0 System.out.println("this.getName()=" + this.getName()); System.out.println("this.isAlive()=" + this.isAlive()); System.out.println("count-----end");}@Overridepublic void run() { System.out.println("run-----begin"); //run办法是t1办法在执行,t1.getName()为Thread1(A)的名称 System.out.println("Thread.currentThread().getName()=" + Thread.currentThread().getName()); System.out.println("Thread.currentThread().isAlive()=" + Thread.currentThread().isAlive());
// public Thread(Runnable target) {
// init(null, target, "Thread-" + nextThreadNum(), 0);
// }
//下面是t1的构造函数,传入的对象实际上是指向cc,所以this.getName()是cc的name-->Thread0 System.out.println("this.getName()=" + this.getName()); System.out.println("this.isAlive()=" + this.isAlive()); //退出这个可能会让了解更好点。 System.out.println("this.currentThread().getName()=" + this.currentThread().getName()); System.out.println("run-----end");}
正文很具体,欢送交换!
二 super.run();
首先,咱们来看一下JDK的Thread源码
private Runnable target;
public void run() {
if (target != null) { target.run(); }
}
代码1:
new Thread(new Runnable() {
@Override public void run() { System.out.println("Run of Runnable"); }
}) {
public void run() { System.out.println("Run of Thread"); }
}.start();
代码2:
new Thread(new Runnable() {
@Override public void run() { System.out.println("Run of Runnable"); }
}) {
public void run() { System.out.println("Run of Thread"); super.run(); }
}.start();
在run()办法中,首先会查看target是否为空,如果不是,则执行该target的run()办法。
那么,对于下面两段代码的执行,也就分明了。
在第一个代码段 1 中,重写了Thread的run()办法,同时传入了一个Runnable对象,该对象也实现了run()办法。该Thread对象调用start()办法后,会执行该对象重写的run()办法,其输入后果也就是Run of Thread,输入完后,run()办法返回,该线程对象的生命周期也就完结了。
在第二个代码段 2 中,同样也重写了Thread的run()办法,同时传入了一个Runnable对象,实现了run()办法。惟一不同的是,在Thread重写的run办法中,在打印输出后,还执行了super.run(),这就有意思了。
首先,该线程启动运行后,执行其重写的run()办法,输入Run of Thread。
接下来调用super.run(),也就是调用超类的run()办法,而该超类的run()办法,也就是JDK定义的Thread类的run(),其执行如上代码段 3 所示;显然target不为空,这时候会调用该对象的run()办法,会输入Run of Runnable.。
如果,下面的Thread并未重写run()办法,那么,执行的后果还是一样。首先会执行该Thread的run()办法,因为此时并未重写该办法,所以还是会调用JDK定以的run()办法,也就是下面的代码段 3,在该代码段中会判断target是否为空,显然不是,所以会调用Runnable对象实现的run()办法。
总结:
对于Thread(Runnable target ...),不论传入的Target是否为空,首先都会执行Thread本人的run()办法。
如果重写了该办法且该办法中没有super.run(),那么是永远不会调用Runnable实现的run()办法;
如果没有重写该办法,则会去判断target是否为空,以此来决定调用target实现的run()办法;
如果重写了该办法,且该办法中有super.run(),如代码2,在执行完该语句之前的所有代码后,会判断target是否为空,以此来决定调用target实现的run()办法,执行完后,接着执行该语句之后的代码。