最近在看一本比较基础的书《Java 多线程编程核心技术》,发现里面有一个关于Thread类的知识点,是我以前没有注意过的,比较有意思, 记录如下。

我们都知道Thread类本身就实现了Runnable接口,因此,我们是可以将一个Thread对象传递给另一个Thread的构造函数的,如下:

MyThread myThread = new MyThread();
Thread t1 = new Thread(myThread);

在你的MyThread里覆盖run方法,写各自的业务逻辑。比如下面的代码:

public class MyThread extends Thread {

    public MyThread() {
        System.out.println("MyThread constructor--- begin");
        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("MyThread constructor--- end");
    }

    @Override
    public void run() {
        System.out.println("run --- begin");
        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("run --- end");
    }
}

测试类如下:

public class ThreadTest {

    public static void main(String[] args) {

        MyThread myThread = new MyThread();
        Thread anotherThread = new Thread(myThread);
        System.out.println("main begin firstThread isAlive() = " + anotherThread.isAlive());
        anotherThread.setName("another");
        anotherThread.start();
        System.out.println("main end firstThread isAlive() = " + anotherThread.isAlive());
    }
}

最后的输出是这样的

MyThread constructor--- begin
Thread.currentThread().getName() = main
Thread.currentThread().isAlive() = true
this.getName() = Thread-0
this.isAlive() = false
MyThread constructor--- end
main begin firstThread isAlive() = false
main end firstThread isAlive() = true
run --- begin
Thread.currentThread().getName() = another
Thread.currentThread().isAlive() = true
this.getName() = Thread-0
this.isAlive() = false
run --- end

这里的核心就在于Thread.currentThread().getName()和this.getName()的区别。(isAlive方法同理) 本质上this.isAlive()方法是针对当前这个线程对象而言的(和普通的Java对象一样),所以上述代码中两个位置的this.isAlive() 都返回的是false,因为我们没有让myThread这个线程执行过。我们一直用这行代码Thread anotherThread = new Thread(myThread)。 执行的都是另外一个线程。

而Thread.currentThread().isAlive()方法是针对当前正在执行的线程,那么这个方法什么时候会返回false呢?可以写出这样 一段代码吗?

需要注意的一点是,Thread的sleep()方法,interrupted()方法都是静态方法,在运行的时候表示的是将当前执行这条语句的线程 休眠、判断中断状态(并清除中断状态),isInterrupted()是实例方法,表示的被调用的线程对象的中断状态。

sleep()方法被中断后,中断状态是会被清除的。即一个正在休眠的线程被中断后,它的中断状态是false。