| 背景

Thread.currentThread() 的返回值是在代码实际运行时候的线程对象,即当前线程。

java中的任何一段代码都是执行在某个线程当中的,执行当前代码的线程就是当前线程

本文中只围绕着Thread.currentThread().getName()所讲

由上可知,getName()返回的是当前线程的名称

| 代码示例

简单示例

① 新建一个currentThread类,继承Thread类,并重写父类的run() 方法

public class currentThread extends Thread{public currentThread(){ System.out.println("currentThread构造方法线程名称:"+Thread.currentThread().getName()); } @Override public void run() { System.out.println("run()线程名称:"+Thread.currentThread().getName()); }
}

② 新建一个测试类,初始化currentThread类对象,并启动子线程

之所以说是启动子线程,是因为JVM启动时会创建一个主线程,就是运行main方法的线程

public class currentThreadTest {public static void main(String[] args) {System.out.println("main名称:"+Thread.currentThread().getName());currentThread thread = new currentThread();// 启动子线程thread.start(); }
}

我们来看运行结果:

① main名称:main
② currentThread构造方法线程名称:main
③ run()线程名称:Thread-0

▶ 输出解析:

第一行输出是main,没有疑问,当前执行的线程就是Main主线程;

仔细看第二行输出,结果是main;为什么是main呢?

主要原因是,我们是在main线程中执行的初始化对象操作,并没有启动一个新的线程!!所以构造方法中的当前线程就是当前执行的main线程

第三行输出是 “Thread-0”,即子线程名称,对线程有所了解的朋友应该知道,Thread类的start()方法是启动一个新的线程,Java API中对于该方法的介绍:

使该线程开始执行;Java 虚拟机调用该线程的 run 方法

因此,t.start()会导致run()方法被调用,run()方法中的内容称为线程体,它就是这个线程需要执行的工作。

用start()来启动线程,实现了真正意义上的启动线程

所以它输出的就是当前运行的子线程名称。此时是有两个线程,一个是Main线程,一个是子线程

那么问题来了?如果我们把  thread.start();  换成  thread.run(); 

执行结果如下:

thread.start()运行结果:run()线程名称:Thread-0
thread.run()运行结果:  run()线程名称:main

解释:  调用start方法可启动线程,而run方法只是thread类中的一个普通方法调用,还是在主线程里执行。也就是说程序中依然只有主线程这一个线程!

且程序执行路径只有一条,顺序执行,等run方法体执行完毕,才继续执行后面的代码

复杂示例

① 同样新建一个currentThread类,继承Thread类,并重写父类的run() 方法

比较Thread.currentThread().getName() 和 this.getName() 的区别

public class currentThread extends Thread{public currentThread2(){System.out.println("构造方法线程名称::"+Thread.currentThread().getName());System.out.println("构造方法this.getName():"+this.getName());}@Overridepublic void run() {System.out.println("run()线程名称:"+Thread.currentThread().getName());System.out.println("run方法this.getName():"+this.getName());}
}

② 新建一个测试类,初始化currentThread类对象,并启动子线程

public class currentThreadTest {public static void main(String[] args) {System.out.println("main名称:"+Thread.currentThread().getName());// this表示构造方法new出来的这个对象currentThread t1 = new currentThread();t1.start();Thread.sleep(500);//main线程休眠500毫秒,目的是让前面的代码充分得到运行// new Thread(Runnable),里面传的是Runnable的实现类// t1对象继承了Thread,而Thread类实现了Runnable接口Thread t2=new Thread(t1);t2.start();}
}

我们来看运行结果:

① main名称:main// 此处的输出调用是:currentThread t1 = new currentThread();
② 构造方法:main
③ 构造方法this.getName():Thread-0// 此处的输出调用是:t1.start();
④ run()线程名称:Thread-0
⑤ run方法this.getName():Thread-0// 此处的输出调用是:t2.start();
⑥ run()线程名称:Thread-1
⑦ run方法this.getName():Thread-0

▶ 输出解析:
①② 上述简单例子已讲,不做分析

第三个输出是 “Thread-0”,即子线程名称,this.getName()中的this对象表示构造方法new出来的对象 new currentThread()的实例,而new出来的对象就是Thread-0

this代表的是本类的实例对象

④⑤ 输出的调用是t.start(),打印的是启动线程的名称

⑥⑦ 仔细看这两个的输出结果:

把t1对象为Runnable接口的实现类作为入参,进行t2对象的初始化 new Thread(Runnable)

代码:Thread t2=new Thread(t1);t2.start();输出结果:run()线程名称:Thread-1 run方法this.getName():Thread-0

▶ 直接输出的是run方法体中的语句块,没有输出构造函数中的语句,因为t1已经被实例化了,作为入参传值,不会再次实例化该对象

由前面简单例子得出,t2.start()的调用,会启动一个新线程,从而触发run方法的调用

故此Thread.currentThread().getName()的调用,得出的当前执行线程名称,就是start()方法新创建的线程 :Thread-1 (此时这里已经有三个线程了,main、Thread-0、Thread-1)

▶ t2对象运行的run方法体中, this.getName() 的调用,打印出来的是 Thread-0 的名称,为什么不是t2本身的名称 Thread-1 呢?

我们来分析下

Thread的初始化对象源码:

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

run()方法源码

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

我们在初始化t2对象的操作是:Thread t2=new Thread(t1);

t1作为target对象传入到的t2实例化中,故t2对象的本身就是t1对象,在run方法中得知,t2.strat()启动的线程触发run的执行,实际上就是执行的t1对象中的run()方法。

所以在调用 Thread.currentThread().getName()  得到的当前运行线程的主体是:Thread-1 , 在调用 this.getName() 时,输出结果是:Thread-0  

因为 this代表的是本类的实例对象 ,t2的对象实例是t1作为入参传入的,所以this指向的是t1

Thread.currentThread().getName()相关推荐

  1. java线程学习-Thread.currentTread().getName()和this.getName()的区别

    很久没有写java程序了,由于为了改变目前的状况,打算花两天时间学习一下java的线程开发和高并发. 线程开发使用thread类,或者runnable接口,而且thread类也是实现了runnable ...

  2. 演示Thread.sleep(100)和Thread.currentThread().isInterrupted()+@Deprecated:将方法标注为废弃的方法...

    package charpter08; public class TestInterrupt01 { public static void main(String[] args) { Processo ...

  3. Thread.currentThread()方法、进程、线程、多线程相关总结(二)

    Thread.currentThread()方法 Thread.currentThread()可以获取当前线程的引用,一般都是在没有线程对象又需要获得线程信息时通过Thread.currentThre ...

  4. Thread.currentThread()、isAlive()、Thread.sleep()的使用

    1.Thread.currentThread()方法: 返回当前正在运行的线程 一个简单的例子: MyThread_7.Java类的构造函数是被main线程调用的,而run()方法是被名为Thread ...

  5. Thread.currentThread()与this的区别

    在自定义线程类时,如果线程类是继承java.lang.Thread的话,那么线程类就可以使用this关键字去调用继承自父类Thread的方法,this就是当前的对象. 另一方面,Thread.curr ...

  6. Thread.currentThread().getContextClassLoader() 和 Class.getClassLoader()区别

    查了一些资料也不是太明白两个的区别,但是前者是最安全的用法 打个简单的比方,你一个WEB程序,发布到Tomcat里面运行. 首先是执行Tomcat org.apache.catalina.startu ...

  7. Thread.currentThread().getContextClassLoader().getResourceAsStream()读取配置文件

    Java中使用的路径,分为两种:绝对路径和相对路径.具体而言,又分为四种: 一.URI形式的绝对资源路径 如:file:/D:/java/eclipse/workspace/j/bin/a URL是U ...

  8. android getid,Process.myTid()和Thread.currentThread().getId()区别

    首先,两个方法都是返回线程ID,但结果是不同的,简单的说 android.os.Process.myTid()是系统级的ID Thread.currentThread().getId()是Java级的 ...

  9. Thread.currentThread().getContextClassLoader()和Class.getClassLoader()区别

    2019独角兽企业重金招聘Python工程师标准>>> What is different between Thread.currentThread().getContextClas ...

最新文章

  1. brain.js 时间序列_免费的Brain JS课程学习JavaScript中的神经网络
  2. Caml Query语句的所有条件
  3. ORACLE常用性能监控SQL【一】
  4. 让我们共同怀揣文学与艺术的梦想
  5. 河北体检系统诚信企业推荐_应用多的隔膜计量泵价格诚信企业推荐
  6. 你好,面试官 | 你拿Java Map考验老干部?
  7. 喜欢的数字:使用一个字典来_数字证书:何时何地使用它们
  8. Java开发知识之Java的包装类
  9. shell脚本中执行python脚本并接收其返回值的例子
  10. java国际软件工程师_JAVA国际软件工程师--学生选课系统
  11. java报错root cause_[Filtered request failed.] with root cause java.io.OptionalDataException
  12. 吉他所有和弦的指型都靠硬记吗?
  13. Ireport 导出pdf 特殊字体设置
  14. 简单排序【左程云Java】
  15. sai椭圆尺子等比例放大或者缩小
  16. 2022-2028年中国异戊二烯行业市场运营格局及前景战略分析报告
  17. Mac Safari浏览器关闭下载压缩包文件后自动解压缩的功能
  18. Heatmap.js – 最强大的 Web 动态热图
  19. 尼得科亚微米级的精密加工技术
  20. 关于“打开数据库时出错: 用户 ‘sa‘ 登录失败。”的解决方法

热门文章

  1. 《机器学习实战》源码和数据集的下载
  2. 字符串函数中的求长度、查找、分割和错误报告函数(strlen,strstr,strtok,strerror)
  3. Python日期的加减
  4. ioinic 怎样配置 android sdk,Nobelioinicijuoja reikšmingus technologijø pokyèius.
  5. ArcMap 导入 wrl_【丽爱妆】导入液怎么用 什么时候用
  6. elementUI表格树动态合并列问题处理(最终版,---新需求)
  7. 持续集成(CI)工具-----jenkins
  8. 使用PongoOS读取苹果ARM64 CPU功能支持寄存器
  9. JavaWeb学习:cookies
  10. java中 toast的意思,英语:toast意思