Thread.currentThread()与this的区别

先看第一个例子:

复制代码
public class MyThread extends Thread {  
    
    public MyThread(){  
          
        System.out.println("------" + "构造函数开始" + "------");  
        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("Thread.currentThread() == this : " + (Thread.currentThread() == this));
        System.out.println("------" + "构造函数结束" + "------");  
          
    }  
      
    @Override  
    public void run(){  
          
        System.out.println("------" + "run()开始" + "------");  
        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("Thread.currentThread() == this : " + (Thread.currentThread() == this));  
        System.out.println("------" + "run()结束" + "------");  
          
    }  
      
}  

public class Main {

    public static void main(String[] args) {
        MyThread myThread = new MyThread();  
        myThread.setName("A");  
        myThread.start();  
    }

}
复制代码

运行结果如下:

复制代码
------构造函数开始------
Thread.currentThread().getName() = main
Thread.currentThread().isAlive() = true
this.getName() = Thread-0
this.isAlive() = false
Thread.currentThread() == this : false
------构造函数结束------
------run()开始------
Thread.currentThread().getName() = A
Thread.currentThread().isAlive() = true
this.getName() = A
this.isAlive() = true
Thread.currentThread() == this : true
------run()结束------
复制代码

解析构造函数部分:

由于构造函数是被main主线程调用的,所以这里的Thread.currentThread()返回的是主线程main。其实就是表明Thread.currentThread()表示当前代码段正在被谁调用。

而this就是只当前线程myThread。至于this.getName()=Thread-0是有其内部机制决定的,源码如下:

    private static int threadInitNumber;
    private static synchronized int nextThreadNum() {
        return threadInitNumber++;
    }
    public Thread() {
        init(null, null, "Thread-" + nextThreadNum(), 0);
    }

从中可以看出线程new的时候就会自动生成一个默认线程名。由于此时该线程还没启动,所以状态是false还未启动。

解析run()方法部分:

由于此时线程开始启动,所以Thread.currentThread()与this指同一个,即当前线程。然而Thread.currentThread()实际依旧表示当前代码段正在被谁调用。this指代的才是真正的当前线程。

下面再看第二个例子,依旧使用上面的线程类代码,只修改测试类如下:

复制代码
public class Main {

    public static void main(String[] args) {
        MyThread myThread = new MyThread();  
        Thread t1 = new Thread(myThread);
        System.out.println("main begin myThread isAlive = " + myThread.isAlive());
        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 myThread isAlive = " + myThread.isAlive());
    }

}
复制代码

主要区别已经表明,就是线程myThread作为参数传入另一个线程。

运行结果如下:

复制代码
------构造函数开始------
Thread.currentThread().getName() = main
Thread.currentThread().isAlive() = true
this.getName() = Thread-0
this.isAlive() = false
Thread.currentThread() == this : false
------构造函数结束------
main begin myThread isAlive = false
main begin t1 isAlive = false
main end t1 isAlive = true
main end myThread isAlive = false
------run()开始------
Thread.currentThread().getName() = A
Thread.currentThread().isAlive() = true
this.getName() = Thread-0
this.isAlive() = false
Thread.currentThread() == this : false
------run()结束------
复制代码

解析中间一部分:

可以发现内部线程myThread始终没有开启过,而外部线程t1在start后开启,而它实际是调用的内部线程myThread的run方法开启的。

解析run()方法部分:

Thread.currentThread()与this指向了不通的线程对象。Thread.currentThread()指向的是外部线程,表示当前方法被外部线程t1调用。this指向的是内部线程myThread,状态依旧是false未开启状态。与main方法中的输出一样。

 

总结:

在线程不作为参数传入另一个线程时,this和Thread.currentThread()【表面上】代表的是同一个对象。而当线程作为参数传入时,this指向当前对象,即内部线程,而Thread.currentThread()指向当前方法被哪个线程调用的那个对象,即外部线程。

posted on   二十年后20  阅读(3382)  评论(0编辑  收藏  举报

编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

导航

统计

点击右上角即可分享
微信分享提示