Thread.currentThread()与this的区别,以及super.run()的作用

一 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");
	}
	
	@Override
	public 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的线程,线程为新建状态。线程名为Thread0
	CountOperate cc = new CountOperate();
	//创建了一个t1的线程,线程为新建状态。线程名为Thread1
    Thread t1 = new Thread(cc);
    System.out.println("main begin t1 isalive="+t1.isAlive());
    //将Thread1的名字改为A
    t1.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");
	}
	
	
	@Override
	public 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()方法,执行完后,接着执行该语句之后的代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值