Java 多线程之 this 与 Thread.currentThread() 的区别

public class Run {

    public static void main(String[] args){
        CountOperate c = new CountOperate();
        Thread t1 = new Thread(c);
        System.out.println("main begin t1 isAlive = " + t1.isAlive());
        t1.setName("A");
        t1.start();
        System.out.println("main end t1 isAlive = " + t1.isAlive());
        System.out.println("main end c isAlive = " + c.isAlive());
    }
}

class CountOperate extends Thread {

    public CountOperate(){
        System.out.println("CountOperate --- begin");
        System.out.println("Thread.currentThread().getName() = " + Thread.currentThread().getName());
        System.out.println("Thread.currentThread().isAlive() = " + Thread.currentThread().isAlive());
        System.out.println("Thread.currentThread() == this : " + (Thread.currentThread() == this));
        System.out.println("this.getName = " + this.getName());
        System.out.println("this.isAlive() = " + this.isAlive());
        System.out.println("CountOperate --- 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("Thread.currentThread() == this : " + (Thread.currentThread() == this));
        System.out.println("this.getName() = " + this.getName());
        System.out.println("this.isAlive() = " + this.isAlive());
        System.out.println("run --- end");
    }
}

结果:

CountOperate --- begin
Thread.currentThread().getName() = main
Thread.currentThread().isAlive() = true
Thread.currentThread() == this : false
this.getName = Thread-0
this.isAlive() = false
CountOperate --- end
main begin t1 isAlive = false
main end t1 isAlive = true
main end c isAlive = false
run --- begin
Thread.currentThread().getName = A
Thread.currentThread().isAlive() = true
Thread.currentThread() == this : false
this.getName() = Thread-0
this.isAlive() = false
run --- end

根据打印的 Log 可以知道调用 CountOperate 构造函数的是 main 线程,因此打印出:

Thread.currentThread().getName() = main
Thread.currentThread().isAlive() = true

而此时还没有启动 CountOperate 子线程所以打印出:

this.getName = Thread-0
this.isAlive() = false

此时 this 代表的是 CountOperate 对象实例,所以

Thread.currentThread() == this : false

这里比较让人疑惑的是this.getName() = Thread-0,这个 Thread-0 是什么东西
通过查看 Thread 源码发现,在 Thread 类的构造方法中,会自动给 name 赋值:

public Thread() {
    init(null, null, "Thread-" + nextThreadNum(), 0);
}

然后执行到:

Thread t1 = new Thread(c);
System.out.println("main begin t1 isAlive = " + t1.isAlive());
t1.setName("A");
t1.start();

Log 打印:

Thread.currentThread().getName = A
Thread.currentThread().isAlive() = true
Thread.currentThread() == this : false
this.getName() = Thread-0
this.isAlive() = false

说明此时的 this 和 Thread.currentThread() 指向不是同一个线程实例

也就是说,this 指向的还是 new CountOperate() 创建的那个线程实例 c,而不是 new Thread(thread) 创建的那个实例即 t1。
查看源代码可以知道:

public Thread(Runnable target) {
    init(null, target, "Thread-" + nextThreadNum(), 0);
}

实际上 new Thread(thread) 会将 thread 应用的对象绑定到一个 private 变量 target 上
在 t1 被执行的时候即 t1.run() 被调用的时候,它会调用 target.run() 方法
再确切的说,在 run 方法被执行的时候,this.getName() 实际上返回的是 target.getName(),而 Thread.currentThread().getName() 实际上是 t1.getName()
因为调用 start() 的线程是 t1,而不是 c,所以 this.isAlive() = false

如果修改 main 中的代码为:

public class Run {
    public static void main(String[] args){
        CountOperate c = new CountOperate();
        c.start();
    }
}

结果:

CountOperate --- begin
Thread.currentThread().getName() = main
Thread.currentThread().isAlive() = true
Thread.currentThread() == this : false
this.getName = Thread-0
this.isAlive() = false
CountOperate --- end
run --- begin
Thread.currentThread().getName = Thread-0
Thread.currentThread().isAlive() = true
Thread.currentThread() == this : true
this.getName() = Thread-0
this.isAlive() = true
run --- end

符合预期

你可能感兴趣的:(Java 多线程之 this 与 Thread.currentThread() 的区别)