• Java编程:Thread.currentThread().getName() 和 this.getName()区别详解


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


    <<Java多线程编程核心技术>>
    这本书里说到了这个:  Thread.currentThread().getName() 
                                        this.getName()
    他俩是有区别的,得到的效应是不一样的,首先,从直观上来说:
    Thread.currentThread().getName() 是一个静态方法
     this.getName()是一个实例方法

    实例方法,一般情况下是:反映这个实例的情况
    静态方法,一般情况下是:反映这个实体的情况
    实例指的就是这个类的对象
    实体却不一样,实体是指正在发生这个作用的实例
     
    上代码:
    1. publicclassMyThread extends Thread{
    2. publicMyThread(){
    3. System.out.println("---MyThread begin---");
    4. System.out.println("Thread.currentThread.getName()="+Thread.currentThread().getName());
    5. System.out.println("this.getName()="+this.getName());
    6. System.out.println(Thread.currentThread()==this);
    7. System.out.println("---MyThread begin---");
    8. }
    9. @Override
    10. publicvoid run(){
    11. System.out.println("---run begin---");
    12. System.out.println("Thread.currentThread.getName()="+Thread.currentThread().getName());
    13. System.out.println("this.getName()="+this.getName());
    14. System.out.println(Thread.currentThread()==this);
    15. System.out.println("---run end ---");
    16. }
    17. publicstaticvoid main(String[] args) throws InterruptedException{
    18. MyThread tt =newMyThread();
    19. Thread t1 =newThread(tt);
    20. t1.setName("test");
    21. t1.start();
    22. }
    23. }
    输出:
    1. ---MyThread begin---
    2. Thread.currentThread.getName()=main //实体是指现在正在发生的线程:main线程
    3. this.getName()=Thread-0 //实例:当前实例是“死的线程”,默认赋值是:Thread-0
    4. false //    实体并不是实例
    5. ---MyThread begin---

    6. ---run begin---
    7. Thread.currentThread.getName()=test //实体是指现在正在发生的线程:test线程
    8. this.getName()=Thread-0 //实例:当前实例是“死的线程”,默认赋值是:Thread-0
    9. false //当前的实体是:test 并不是,tt这个对象的死线程
    10. ---run end ---
    调用MyThread构造函数的是main线程
    Thread.currentThread().getName()=main
    Thread.currentThread().isAlive()=true

    而此时还没有启动MyThread子线程,所以打印出
    this.getName=Thread-0
    this.isAlive()=false

    此时this代表的是MyThread对象实例,所以
    Thread.currentThread()==this :false


    this.getName() = Thread-0 是为什么呢
    通过查看Thread源码发现,在Thread类的构造方法中,默认会自动给name赋值:
    1. publicThread(Runnable target){
    2. init(null, target,"Thread-"+ nextThreadNum(),0);
    3. }
    在Thread源码中实际上new Thread(tt)会将tt应用的对象绑定到一个private变量target上,
    在t1被执行的时候即t1.run()被调用的时候,它会调用target.run()方法,
    也就是说它是直接调用tt对象的run方法,也就是说,在run方法被执行的时候,
    this.getName()实际上返回的是target.getName(),而Thread.currentThread().getName()实际上是t1.getName()
    修改代码直接执行MyThread的线程:
    1. publicstaticvoid main(String[] args) throws InterruptedException{
    2. MyThread tt =newMyThread();
    3. tt.setName("test");
    4. tt.start();
    5. }
     
    输出:
    1. ---MyThread begin---
    2. Thread.currentThread.getName()=main
    3. this.getName()=Thread-0
    4. false
    5. ---MyThread begin---
    6. ---run begin---
    7. Thread.currentThread.getName()=test
    8. this.getName()=test
    9. true
    10. ---run end ---
     
    总结几点:
    • 一个进程里main是一开始就活着的,但是,它跟main方法半毛钱关系都没有,仅仅是同名罢了
    • 谁调用了start函数,谁才把自己交给线程调度器,谁才是活着的线程,否则,管你继承啥,还是实现啥,都是一个普通的对象
    • 实现了Runable接口的对象具有运行线程的资格,但是,只要它不被start,它就是一个普通的对象,有资格,并不代表它就是线程,线程是活着的东西,对象是死的
    • 线程可以级级包裹嵌套,就像上边一样,它运行的是:target的run
    • 自己调用run的话,仅仅就是一个函数调用,要让调度器去调用,它才是一个线程
  • 相关阅读:
    服务端测试之接口测试工具——postman
    服务端测试之接口测试初探
    项目()已配置为使用IIS Web服务器,但此计算机上...
    其他信息: 在分析完成之前就遇到流结尾。
    WPF 打开指定文件路径的文件资源管理器
    Power BI 可视化交互/视觉对象交互
    ASP.NET 前端Ajax获取数据并刷新
    异常详细信息: System.ArgumentException: 不支持关键字: “metadata”。
    设计模式→单例模式
    <转>记dynamic的一个小坑 -- RuntimeBinderException:“object”未包含“xxx”的定义
  • 原文地址:https://www.cnblogs.com/xujintao/p/7380269.html
Copyright © 2020-2023  润新知