Thread.currentThread()。interrupt()与来自Runnable#run()内的this.interrupt()

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Thread.currentThread()。interrupt()与来自Runnable#run()内的this.interrupt()相关的知识,希望对你有一定的参考价值。

我需要弄清楚为什么我在互联网上找到的关于如何从interrupt()方法中捕获Runnable#run()的每个例子,它们都看起来像这样:

while (Thread.currentThread().isInterrupted()) {
    //foo();
    try {
        Thread.sleep(1000);
    } catch(InterruptingException e) {
        Thread.currentThread().interrupt();
    }
    //foo();
}

我现在已经足够了解线程(我想是这样)而且我无法理解为什么如果我们在run方法内部并不意味着我们可以用Thread.currentThread()替换this

答案

如果我们在run方法内部并不意味着Thread.currentThread()==这个?

runRunnable方法中,this不等于current thread,它代表当前的Runnable实例。

Runnable只是一个普通的对象,可以用来构造一个新的线程。当你使用Runnable构建Thread时:

Runnable runnable = ...
Thread thread = new Thread(runnable);

线程和runnable仍然是不同的对象。


这个例子表明它们是不同的东西:

public static void main (String[] args) throws Throwable {
    Runnable runnable = new Runnable() {
        @Override
        public void run() {
            System.out.println("inner runnable: " + this);   // inner runnable: com.Test$1@34ce8af7
        }
    };


    Thread thread = new Thread(runnable);

    System.out.println("thread:  " + thread); // thread:  Thread[Thread-0,5,main]
    System.out.println("runnable:  " + runnable); // runnable:  com.Test$1@34ce8af7

    thread.start();
    thread.join();
}

值得注意的另一件事是java.lang.Thread也实现了Runnable接口,所以如果你直接创建一个Thread并覆盖run方法,this关键字和Thread.currentThread都将引用当前线程实例。

Thread thread = new Thread() {
    @Override
    public void run() {
        // this == Thread.currentThread()
    }
};

您也可以在任何方法中引用当前线程,无论您是否可以在run方法中,例如,在main方法中:

public static void main (String[] args) throws Throwable {
    Thread.currentThread().interrupt();
}
另一答案

this内部的Runnable#run()指的是Runnable对象,而不是封闭的Thread对象。在这种情况下Thread.currentThread() != this

但是,如果创建如下所示的线程对象,则不鼓励:

Thread thread = new Thread() {
  @Override
  public void run() {
    System.out.println(Thread.currentThread() == this);
  }
};

然后Thread.currentThread() == this

另一答案

如果this是线程,你只能用Thread.currentThread()替换this。这需要扩展Thread,这很少是一个好主意。

从来没有像你这样需要使用Thread.currentThread()作为例外,无论如何都可以打破循环。

try {
    while (true){
        try {
            //foo();
            Thread.sleep(1000);
        } finally {
            //foo();
        }
    }
} catch (InterruptingException e){
     // if the thread needs to continue after an interrupt.
     Thread.currentThread().interrupt();
}

我倾向于假设一个被中断的线程应该尽快停止,在这种情况下,理想情况下中断之后不应该有任何工作。

以上是关于Thread.currentThread()。interrupt()与来自Runnable#run()内的this.interrupt()的主要内容,如果未能解决你的问题,请参考以下文章

为啥在实现 Runnable 时使用 Thread.currentThread().isInterrupted() 而不是 Thread.interrupted()?

Thread.currentThread()与this的区别,以及super.run()的作用

为啥在 catch InterruptException 块中调用 Thread.currentThread.interrupt()?

Java多线程之this与Thread.currentThread()的区别

Thread.CurrentThread.CurrentUICulture 没有正确返回国家

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