【问题标题】:Why isInterrupted() gives other result than Thread.currentThread().isInterrupted() (JAVA)为什么 isInterrupted() 给出的结果不是 Thread.currentThread().isInterrupted() (JAVA)
【发布时间】:2015-02-20 12:20:03
【问题描述】:

我研究java线程,一时看不懂: 在以下代码中

public class ThreadsTest {
    public static void main(String[] args) throws Exception{

        ExtendsThread extendsThread = new ExtendsThread();
        Thread et = new Thread(extendsThread);
        et.start();    
        Thread.sleep(1500);
        ir.interrupt();               
    }      
}

public class ExtendsThread extends Thread {
    private Thread currentThread = Thread.currentThread();
    public void run() {
        while (!currentThread .isInterrupted()) {}
        System.out.println("ExtendsThread " + currentThread().isInterrupted());

    }
}

线程不会停止。 但是如果在 ExtendsThread 类中我检查while (!Thread.currentThread().isInterrupted()) 线程停止。 为什么private Thread currentThread = Thread.currentThread(); 不引用当前线程?

【问题讨论】:

  • 这段代码能编译吗? ir 是什么?
  • @piotrek, ir 可能是一个错字,应该是et
  • 对不起,我的错……应该是“et”……
  • 您的ExtendsThread 类永远不会用作Thread(即,您永远不会调用它的start() 方法)。您仅将其用作Runnable。你不妨写class ExtendsThread implements Runnable,除此之外,你可能还想更改它的名称。

标签: java multithreading


【解决方案1】:

为什么私有Thread currentThread = Thread.currentThread(); 不引用当前线程?

因为在这个变量初始化的时候,你在主线程上。 (当您执行ExtendsThread extendsThread = new ExtendsThread(); 时,该变量被初始化,这是从main 完成的。)


但是,代码还有其他问题。

  • 您正在检查 currentThread 而不是 this 线程上的中断。因此,首先将ExtendsThread 代码更改为:

    class ExtendsThread extends Thread {
        public void run() {
            while (!isInterrupted()) {
            }
            System.out.println("ExtendsThread " + isInterrupted());
        }
    }
    
  • 然后你把继承搞砸了。当你这样做时:

    ExtendsThread extendsThread = new ExtendsThread();
    Thread et = new Thread(extendsThread);
    

    这意味着您将一个线程包裹在另一个线程中。 (所以当你中断时,你是在中断外线程,但你正在检查内线程上的中断。)你可能只是想摆脱包装线程,然后做

    ExtendsThread et = new ExtendsThread();
    

这是您代码的完整工作版本:

public class ThreadsTest {

    public static void main(String[] args) throws Exception{
        ExtendsThread et = new ExtendsThread();
        et.start();
        Thread.sleep(1500);
        et.interrupt();
    }
}

class ExtendsThread extends Thread {
    public void run() {
        while (!isInterrupted()) {
        }
        System.out.println("ExtendsThread " + isInterrupted());
    }
}

【讨论】:

  • 不要将Thread 与线程混淆。没有“内线”。本例中的代码创建了两个Thread objects,但它只创建了一个新线程。调用new Thread(...) 时会创建一个Thread 对象,但直到程序调用et.start() 才会创建实际线程。示例代码不使用ExtendsThread 对象作为Thread(即,从不调用其start() 方法)。它只将该对象用作Runnable
【解决方案2】:

当您创建ExtendsThread 时,您将调用构造函数的线程分配给currentThread。所以你的currentThread 并不是你想象的那样。

【讨论】:

    【解决方案3】:

    你应该在run() 里面做Thread currentThread = Thread.currentThread();。否则 currentThread 指的是主线程(构造对象的线程)但是run是由不同的线程执行的

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-05-30
      • 2017-10-06
      • 1970-01-01
      • 2018-09-16
      • 1970-01-01
      • 2013-02-03
      • 1970-01-01
      相关资源
      最近更新 更多