多线程--this和Thread.currentThread()详解

在看多线程编程核心技术的时候,有一段代码让我很困惑,所以在这里记录一下。
public class isalive {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		//Thread.currentThread().getName();
		CountOperate countOperate=new CountOperate();
		Thread t1=new Thread(countOperate);
		System.out.println("main begin t1 isalive  "+t1.isAlive());
		t1.setName("a");
		t1.start();
		System.out.println("main end  "+t1.isAlive());
	}

}

class CountOperate extends Thread{
	public CountOperate(){
		System.out.println("构造函数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.Alive  "+this.isAlive());
		System.out.println("测试:"+Thread.currentThread().getName()==this.getName());//添加的代码,为了测试是否相等
		System.out.println("构造函数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("测试:"+Thread.currentThread().getName()==this.getName());//为了测试是否相等
		System.out.println("this.getname  "+this.getName());
		System.out.println("this.Alive  "+this.isAlive());
		System.out.println("run end");
	}
}

问题就是这边的Thread.currentThread()和this有上面不同,我们先看一下运行之后的输出。


首先从第2,3行输出可以知道,countoperate的构造函数是在主线程中运行的,这个没有疑问。

第3,4行输出了thread-0,和false,Thread.currentThread()和this也并不是一个引用,因为this指向的是countoperate对象实例,该实例继承thread,可以调用其中的getname(),isalive()方法。然后我就想知道为什么它这边this.getname()为什么会拿出个thread-0出来。我们来看源码。

首先是thread的构造函数

  public Thread() {
        init(null, null, "Thread-" + nextThreadNum(), 0);
    }
private static int threadInitNumber;//线程的id也就是通过这个静态变量来设置的。

nextThreadNum()方法

 private static synchronized int nextThreadNum() {
        return threadInitNumber++;
    }

在进去Init()方法,因为这个方法里面东西很多,我们只看我们需要的,name参数

 private void init(ThreadGroup g, Runnable target, String name,
                      long stackSize) {
        this.target=target;
        this.group = g;
        this.daemon = parent.isDaemon();
        this.priority = parent.getPriority();
        this.name = name.toCharArray();//在这里将传入的参数赋值给name,也就是线程的名称,在通过getname()来获取。

继续往下看,从run函数里面的输出可以知道,当countoperate作为参数传给t1线程,t1线程开启时,这时候this指向的还是new countoperate的线程实例,而不是线程t1,为什么呢?明明是用线程t1开启调用run方法啊。

还是要看thread源码中另一个构造函数,countoperate作为target参数传给这个线程,当执行t1.run()的时候,本质上调用还是target.run().所有this,getname()得到的还是thread-0.

 public void run() {
        if (target != null) {
            target.run();
        }
    }
 public Thread(Runnable target) {
        init(null, target, "Thread-" + nextThreadNum(), 0);
    }

猜你喜欢

转载自blog.csdn.net/qq_37891064/article/details/79714994