Java Thread.currentThread().getName() 和 this.getName()区别详解

 更新时间:2022年02月21日 08:39:42   作者:经典鸡翅  
本文主要介绍了Thread.currentThread().getName() 和 this.getName()区别详解,TestThread testThread = new TestThread();

currentThread的详解

currentThread方法是Thread类的一个静态方法,用来获取当前运行的代码段,正在被哪个线程调用。我们先来看一眼源码。

是一个native方法。直接与系统层面做交互。
下面看一段代码

 public static void main(String[] args) {
        String name = Thread.currentThread().getName();
        System.out.println(name);
    }

输出的结果为main。

为什么为main呢?

java的项目在启动的时候,会创立一个进程,这个进程同样也是一个线程,在java里面他就叫做main线程。他的名字在设定的时候就是main。我们可以看到上面的代码就是在main方法下执行的,也就是由main线程来执行,所以我们打印出来的名字是main。

创建一个新的线程

来看下面的一行代码,我们创建一个新的线程,并且在线程创建的构造方法和其实际执行的run方法内,增加打印出当前执行线程的名称。

public class TestThread extends Thread {

    public TestThread() {
        System.out.println("构造方法:" + Thread.currentThread().getName());
    }

    @Override
    public void run() {
        System.out.println("run方法:" + Thread.currentThread().getName());
    }

    public static void main(String[] args) {
        TestThread testThread = new TestThread();
        testThread.start();
    }

}

我们运行一下,看到结果

构造方法:main
run方法:Thread-0

如何理解上述的情况呢?

我们先来看构造方法这一行。

TestThread testThread = new TestThread();

这里我们只是声明了一个线程对象类,这个新的线程没有创建也没有启动,我们仅仅把它理解为一个普通对象即可。那么由于是在main方法里面,那么执行他的一定是main线程,所以可以看到构造方法输出的结果是main。
再来看start方法里面,为什么变成了thread-0了呢。
我们知道java的多线程创建的一种方式就是继承thread类。然后实现里面的run方法。这样当线程start的时候,就会调用内部的start0的本地方法,实际就是会执行run的实现方法。当run方法执行的时候,一定是由我们创建的线程去执行的,而不是main线程,所以我们就可以得知打印出来的是新线程的名字thread0。

为什么新线程的名字为thread0呢?

我们是采用继承thread类的形式来创建线程的,那么在我们构造的时候,一定会执行父类的构造方法。我们是一个空参构造,那么我们就要看下父类的空参构造是什么样的。看一下源码

可以看到,里面有一个name参数,已经给我们拼接了一个thread-后面是加了一个变量,我们继续看看这个变量是什么

一个同步的静态方法,再来看看变量的值。

一个静态的int型变量,由此我们知道int的初始值就是0。我们先获取到了0然后又执行了++。其他线程再次初始化的时候就是从1开始了。因为加了同步锁的关键字,我们不用害怕数据会乱掉。
所以我们就知道了新线程的名字为thread-0的来源。

再看一种带this的情况

public class TestThread extends Thread {

    public TestThread() {
        System.out.println("构造方法开始!");
        System.out.println("构造方法:" + Thread.currentThread().getName());
        System.out.println("构造方法的this名称:" + this.getName());
        System.out.println("构造方法结束!");
    }

    @Override
    public void run() {
        System.out.println("run方法开始!");
        System.out.println("run方法:" + Thread.currentThread().getName());
        System.out.println("run方法的this名称:" + this.getName());
        System.out.println("run方法结束!");
    }

    public static void main(String[] args) {
        TestThread testThread = new TestThread();
        testThread.start();
    }

}

执行的结果如下:

构造方法开始!
构造方法:main
构造方法的this名称:Thread-0
构造方法结束!
run方法开始!
run方法:Thread-0
run方法的this名称:Thread-0
run方法结束!

我们发现构造的this名称 为thread-0。这个不难理解,this指的是当前对象的名称。因为我们的线程在初始化的时候有了name,所以是thread-0。

创建的线程setName的情况

public class TestThread extends Thread {

    public TestThread() {
        System.out.println("构造方法开始!");
        System.out.println("构造方法:" + Thread.currentThread().getName());
        System.out.println("构造方法的this名称:" + this.getName());
        System.out.println("构造方法结束!");
    }

    @Override
    public void run() {
        System.out.println("run方法开始!");
        System.out.println("run方法:" + Thread.currentThread().getName());
        System.out.println("run方法的this名称:" + this.getName());
        System.out.println("run方法结束!");
    }

    public static void main(String[] args) {
        TestThread testThread = new TestThread();
        testThread.setName("test");
        testThread.start();
    }

}

看一下执行的结果

构造方法开始!
构造方法:main
构造方法的this名称:Thread-0
构造方法结束!
run方法开始!
run方法:test
run方法的this名称:test
run方法结束!

这里有人可能就要问了,为啥构造方法的this名称为thread-0。实际run的时候就变为test了呢。
这是因为我们在构造对象的时候,对象还不完整,没有执行到setName这一步。所以二者不一致。

最后看一段复杂的代码

public class TestThread extends Thread {

    public TestThread() {
        System.out.println("构造方法开始!");
        System.out.println("构造方法:" + Thread.currentThread().getName());
        System.out.println("构造方法的this名称:" + this.getName());
        System.out.println("构造方法结束!");
    }

    @Override
    public void run() {
        System.out.println("run方法开始!");
        System.out.println("run方法:" + Thread.currentThread().getName());
        System.out.println("run方法的this名称:" + this.getName());
        System.out.println("run方法结束!");
    }

    public static void main(String[] args) {
        TestThread testThread = new TestThread();
        Thread thread = new Thread(testThread);
        System.out.println("新线程thread的名称:" + thread.getName());
        thread.setName("test");
        thread.start();
    }

}

可以看到如下的结果

构造方法开始!
构造方法:main
构造方法的this名称:Thread-0
构造方法结束!
新线程thread的名称:Thread-1
run方法开始!
run方法:test
run方法的this名称:Thread-0
run方法结束!

我们根据结果来看,构造方法的打印,和上面解释的如出一辙。我们重点关注一下新线程的打印,这里为什么是1呢,因为我们上面初始化0之后已经++所以为1。
run方法为test是因为我们实际执行的线程Thread thread = new Thread(testThread);所以我们获取到的名称是thread的名称为test。
那么run方法的this名称为什么是thread-0呢。因为this.getName获取到的是当前对象的名称。我们的当前对象是TestThread。他的线程名称从未被改变过,所以我们拿到了thread-0。

总结

currentThread的getName代表当前执行线程的名称,this.getName代表对象的名称。this.getName()实际上返回的是target.getName(),而Thread.currentThread().getName()实际上是thead.getName()。

到此这篇关于Java Thread.currentThread().getName() 和 this.getName()区别详解的文章就介绍到这了,更多相关Thread.currentThread().getName() 和 this.getName()区别 内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • JAVA字符串占位符使用方法实例

    JAVA字符串占位符使用方法实例

    今天同事又问起类似符串占位符使用的功能,所以下面这篇文章主要给大家介绍了关于JAVA字符串占位符使用的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-11-11
  • java 中同步方法和同步代码块的区别详解

    java 中同步方法和同步代码块的区别详解

    这篇文章主要介绍了java 中同步方法和同步代码块的区别是什么的相关资料,需要的朋友可以参考下
    2017-02-02
  • java8 计算时间差的方法示例

    java8 计算时间差的方法示例

    这篇文章主要介绍了java8 计算时间差的方法示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-10-10
  • IDEA中创建maven项目webapp目录无法识别即未被标识的解决办法

    IDEA中创建maven项目webapp目录无法识别即未被标识的解决办法

    在学习SpringMVC课程中,基于IDEA新建maven项目模块后,webapp目录未被标识,即没有小蓝点的图标显示,所以本文给大家介绍了IDEA中创建maven项目webapp目录无法识别即未被标识的解决办法,需要的朋友可以参考下
    2024-03-03
  • Maven工程pom中如何定义jdk版本

    Maven工程pom中如何定义jdk版本

    这篇文章主要介绍了Maven工程pom中如何定义jdk版本,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-12-12
  • IDEA断点调试,断点不起作用的解决

    IDEA断点调试,断点不起作用的解决

    这篇文章主要介绍了IDEA断点调试,断点不起作用的解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-03-03
  • Spring MVC 注解自动扫描失效原因分析

    Spring MVC 注解自动扫描失效原因分析

    这篇文章主要介绍了Spring MVC 注解自动扫描失效原因分析,非常不错,具有参考借鉴价值,需要的朋友可以参考下
    2016-07-07
  • 详解SpringBoot如何优雅的处理免登录接口

    详解SpringBoot如何优雅的处理免登录接口

    在项目开发过程中,会有很多API接口不需要登录就能直接访问,比如公开数据查询之类的,常规处理方法基本是 使用拦截器或过滤器,拦截需要认证的请求路径,本文介绍一个更优雅的方法自定义注解的方式,文中通过代码示例介绍的非常详细,需要的朋友可以参考下
    2024-01-01
  • Java8通过CompletableFuture实现异步回调

    Java8通过CompletableFuture实现异步回调

    这篇文章主要介绍了Java8通过CompletableFuture实现异步回调,CompletableFuture是Java 8 中新增的一个类,它是对Future接口的扩展,下文关于其更多相关详细介绍需要的小伙伴可以参考一下
    2022-04-04
  • Java 集合中的类关于线程安全

    Java 集合中的类关于线程安全

    这篇文章主要介绍了Java 集合中的类关于线程安全的相关资料,需要的朋友可以参考下
    2017-01-01

最新评论