2
class Thread3_1 extends Thread {
  public static int count = 0;
  String tname1;
  public Thread3_1(String threadname) {
    tname1 = threadname;
  }
  public void run() {
    for (int i = 1; i <= 10; i++) {
      System.out.println(tname1 + " : " + i);
      count++;
      if (count == 2) {
        try {
          sleep(1000);
          count = 0;
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
      }
    }
    if (isInterrupted()) {
      System.out.println("Stop Thread");
      return;
    }
  }
}

class Thread3_2 extends Thread {
  String tname2;
  public Thread3_2(String threadname) {
    tname2 = threadname;
  }
  @Override
  public void run() {
    for (int i = 1; i <= 10; i++) {
      System.out.println(tname2 + " : " + i);
      if (i == 5) {
        Thread.currentThread().interrupt();
        System.out.println("Going to interrupt Thread1");
      }
    }
  }
}

给定后线程正在执行interrupt()

4

5 回答 5

3

中断一个线程只是true为这个线程设置一个中断标志。

线程本身有责任定期检查此标志的值并在run()它为真时尽快停止执行(通过从方法返回)。

如果在线程休眠时设置了中断标志(或者当它在诸如 、 等的阻塞调用wait()中被阻塞时await()),阻塞方法会抛出一个 InterruptedException 。发现此异常并尽快停止执行也是线程的责任。

您的第一个线程定期检查标志并在它为真时退出,但在捕获 InterruptedException 时无法这样做。

您的第二个线程会自行中断,但这样做时不会从其run()方法返回。

于 2013-04-15T11:58:52.090 回答
1

您中断 Thread3_2 而不是 Thread3_1。

在您正在调用的 Thread3_2 的运行方法中

Thread.currentThread().interrupt();

这将向当前正在执行的线程发送一个中断,这是 Thread3_2 的一个实例。如果要中断 Thread3_1,则需要对该线程的引用。

例如:

class Thread3_2 extends Thread{

    Thread threadToInterrupt;

    public Thread3_2(Thread threadToInterrupt) {
        this.threadToInterrupt = threadToInterrupt;
    }

    @Override
    public void run() {
        for (int i = 1; i <= 10; i++) {
            System.out.println(tname2+ " : " +i);
            if(i == 5){
                threadToInterrupt.interrupt();
                System.out.println("Going to interrupt Thread1");
            }
        }
    }
}
于 2013-04-15T11:58:24.810 回答
0

来自 Java 教程:

很多抛出InterruptedException的方法,比如sleep,被设计成取消它们当前的操作,并在收到中断时立即返回。

如果一个线程很长时间没有调用抛出 InterruptedException 的方法怎么办?然后它必须定期调用 Thread.interrupted,如果收到中断则返回 true。*

*换句话说:其他不抛出 InterruptedException 的方法必须定期调用 Thread.interrupted,如果收到中断则返回 true。

在这里解释:http: //docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html

于 2013-04-17T01:58:55.827 回答
0

您要中断的线程必须设计为通过从 run() 方法优雅退出来处理中断请求。这意味着确保 InterruptedExceptions 导致代码跳出循环。这也意味着在循环内定期检查中断标志。还有其他更难处理的场景,例如不可中断的 IO 操作。

目标线程将自己重新标记为中断也是一个很好的做法,这样调用堆栈中的调用者也可以得到中断的指示(在 catch 语句中使用 Thread.currentThread().interrupt())。

于 2013-04-15T12:03:32.217 回答
0

如上所述,您需要中断 Thread3_1 而不是 Thread3_2。应用此修复程序后,您仍然会遇到一个问题:

try {
              sleep(1000); 
              count = 0;
            } catch (InterruptedException e) {
              e.printStackTrace();
            }

因此,如果在睡眠中断发生时,中断标志将被清除并且 isInterrupted() 方法将返回 false,因此将不满足以下条件:

if (isInterrupted()) {
          System.out.println("Stop Thread");
          return;
        }

所以你也需要在 catch 块中处理这个问题,即如果在 catch 中返回(被中断)

于 2013-04-15T12:14:46.183 回答