线程中Thread.currentThread()与this的区别

this 关键字是 Java 常用的关键字,可用于任何实例方法内指向当前对象,也可指向对其调用当前方法的对象,或者在需要当前类型对象引用时使用。

Thread.currentThread()官方API说明:返回对当前正在执行的线程对象的引用

public static Thread currentThread()
 返回对当前正在执行的线程对象的引用。
 返回:
  当前执行的线程。

尽管this与Thread.currentThread() 都可以获取到Thread的引用,但是在某种情况下获取到的引用是有差别的,下面进行举例说明

package com.lxf;

/**
 * @author lxf
 * @version v1.0
 * @date 2019/4/17 11:08
 */
public class MyThread extends Thread {

    public MyThread(){

        System.out.println("------" + "构造函数开始" + "------");
        Thread testThread = Thread.currentThread();
        System.out.println("Thread.currentThread().getName() = " + testThread.getName());
        System.out.println("Thread.currentThread().isAlive() = " + testThread.isAlive());
        System.out.println("this.getName() = " + this.getName());
        System.out.println("this.isAlive() = " + this.isAlive());
        System.out.println("Thread.currentThread() == this : " + (testThread == this));
        System.out.println("------" + "构造函数结束" + "------");

    }

    @Override
    public void run(){

        Thread testThread = Thread.currentThread();
        System.out.println("------" + "run()开始" + "------");
        System.out.println("Thread.currentThread().getName() = " + testThread.getName());
        System.out.println("Thread.currentThread().isAlive() = " + testThread.isAlive());
        System.out.println("this.getName() = " + this.getName());
        System.out.println("this.isAlive() = " + this.isAlive());
        System.out.println("Thread.currentThread() == this : " + (testThread == this));
        System.out.println("------" + "run()结束" + "------");

    }

    public static void main(String[] args) throws InterruptedException {
        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().getName() = main
Thread.currentThread().isAlive() = true

查看Thread类原码可看到

 /**
     * Allocates a new {@code Thread} object. This constructor has the same
     * effect as {@linkplain #Thread(ThreadGroup,Runnable,String) Thread}
     * {@code (null, null, gname)}, where {@code gname} is a newly generated
     * name. Automatically generated names are of the form
     * {@code "Thread-"+}<i>n</i>, where <i>n</i> is an integer.
     */
    public Thread() {
        init(null, null, "Thread-" + nextThreadNum(), 0);
    }

不指定Thread名字时,Thread会自动给name赋值,此时this指向的MyThread子线程,但子线程还没有启动所以

this.getName() = Thread-0
# 子线程未启动
this.isAlive() = false
# 非同一个对象
Thread.currentThread() == this : false

然后myThread子线程启动

------run()开始------
# 设置了线程名myThread.setName("A")
Thread.currentThread().getName() = A
# 线程已启动
Thread.currentThread().isAlive() = true
this.getName() = A
this.isAlive() = true
# 同一指向
Thread.currentThread() == this : true
------run()结束------

程序若执行main方法

 public static void main(String[] args) throws InterruptedException {
        MyThread myThread = new MyThread();       
        Thread thread = new Thread(myThread);
        System.out.println("main begin thread isAlive=" + thread.isAlive());
        thread.setName("A");
        thread.start();
        System.out.println("main end thread isAlive=" + thread.isAlive());

 }

执行结果,此时的this和Thread.currentThread()指向不是同一个线程实例。
也就是说,this指向的还是new MyThread()创建的那个线程实例,而不是new Thread(thread)创建的那个实例即thread。

------run()开始------
Thread.currentThread().getName() = A
Thread.currentThread().isAlive() = true
this.getName() = Thread-0
this.isAlive() = false
Thread.currentThread() == this : false
------run()结束------

new Thread(Runnable target)方法

/**
     * Allocates a new {@code Thread} object. This constructor has the same
     * effect as {@linkplain #Thread(ThreadGroup,Runnable,String) Thread}
     * {@code (null, target, gname)}, where {@code gname} is a newly generated
     * name. Automatically generated names are of the form
     * {@code "Thread-"+}<i>n</i>, where <i>n</i> is an integer.
     *
     * @param  target
     *         the object whose {@code run} method is invoked when this thread
     *         is started. If {@code null}, this classes {@code run} method does
     *         nothing. 其 run 方法被调用的对象。
     */
    public Thread(Runnable target) {
        init(null, target, "Thread-" + nextThreadNum(), 0);
    }

所以:将线程对象以构造参数的方式传递给Thread对象进行start()启动线程,我们直接启动的线程实际是thread,而作为构造参数的myThread,赋给Thread类中的属性target,之后在Thread的run方法中调用target.run();此时Thread.currentThread()是Thread的引用thread, 而this依旧是MyThread的引用,所以是不一样的,打印的内容也不一样。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值