多线程的this.getName()与Thread.currentThread().getName为何有时不一样

今天看了多线程的书,作者阐述了两者有时不一样,但是并没有说明原因,好奇,自己对着代码改了一下。

这是线程类,这里我自己添加了一个构造方法用来基于本线程创建新线程(说法可能不太对),

package test;

public class CountOprate extends Thread {
	CountOprate() {
		System.out.println("CountOprate --- 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("CountOprate --- end ");
	}
	CountOprate(Thread target){//自己写的
		super(target);
		System.out.println("CountOprate2 --- 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("CountOprate2 --- end ");
	}
	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 ");
		}

}

这里是test类,用于测试,这里先来看注释掉第七行的结果,这是正常的方式,调用Thread的构造方法

package test;

public class CountOprateTest {
	public static void main(String[] String) throws InterruptedException {
		CountOprate co = new CountOprate();
		Thread t1 = new Thread(co);
//		CountOprate t1  = new CountOprate(co);
		System.out.println("main begin t1 isAlive " + t1.isAlive());
		t1.start();
		System.out.println("main end t1 isAlive " + t1.isAlive());
		// co.start();
		System.out.println("co isAlive " + co.isAlive());
	}
	
}

结果为:

CountOprate --- begin 
Thread.currentThread().getName() = main
Thread.currentThread().isAlive() = true
this.getName() = Thread-0
this.isAlive() = false
CountOprate --- end 
main begin t1 isAlive false
main end t1 isAlive true
co isAlive false
run --- begin 
Thread.currentThread().getName() = Thread-1
Thread.currentThread().isAlive() = true
this.getName() = Thread-0
this.isAlive() = false
run --- end 

解开第七行注释,注释第六行,使用自己定义的构造器,结果是这样的:

CountOprate --- begin 
Thread.currentThread().getName() = main
Thread.currentThread().isAlive() = true
this.getName() = Thread-0
this.isAlive() = false
CountOprate --- end 
CountOprate2 --- begin 
Thread.currentThread().getName() = main
Thread.currentThread().isAlive() = true
this.getName() = Thread-1
this.isAlive() = false
CountOprate2 --- end 
main begin t1 isAlive false
main end t1 isAlive true
co isAlive false
run --- begin 
Thread.currentThread().getName() = Thread-1
Thread.currentThread().isAlive() = true
this.getName() = Thread-1
this.isAlive() = true
run --- end 

可以看到第一种情况使用了Thread的构造器,this.getName()却指向之前线程(即构造器中的参数线程),

而第二种情况使用了自己的构造方法,则this与Thread.currentThread()一致,

这是为什么呢???

我们来一层一层找,这是Thread构造方法 

public Thread(Runnable target) {
        init(null, target, "Thread-" + nextThreadNum(), 0);
    }
private void init(ThreadGroup g, Runnable target, String name,
                      long stackSize) {
        init(g, target, name, stackSize, null);
    }

public void run() {
        if (target != null) {
            target.run();
        }
    }

我们好像发现了什么,,,这里的构造器,是创建线程,直接传递target,之后run方法就更省力了,target.run(),

这不就是直接调用target线程的run方法吗,那this指向target线程就理所当然了


看回来,我自己线程类里面那个构造器虽然也是调用的Thread(Runnable target),但是run方法调用权由Thread父类调用改为了CountOprate类自己调用,所以this指向是正常的

CountOprate(Thread target){
		super(target);
		System.out.println("CountOprate2 --- 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("CountOprate2 --- end ");
	}

详细来说, 第一种调用的时候作为一个Thread类而不是CountOprate类,调用的是Thread的run方法,而Thread的run方法是直接使用target调用target线程的run方法 

所以this指向target线程 第二种方式:调用时作为一个CountOprate类,调用了CountOprate的run方法,所以this指向了这个线程,与Thread.currentThread一致



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值