在给出“interrupt()”之后线程正在执行

时间:2013-04-15 11:52:06

标签: java multithreading

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()

后线程正在执行

5 个答案:

答案 0 :(得分:3)

中断线程只会为此线程设置一个中断标志true

线程本身有责任重新检查此标志的值,并在它为真时立即停止执行ASAP(通过从run()方法返回)。

当线程处于休眠状态时(或者在wait()await()之类的bocking调用中被阻塞时)设置了中断标志时,阻塞方法会抛出InterruptedException。线程也负责解决此异常并停止执行ASAP。

您的第一个线程会定期检查该标志并在其为真时退出,但在捕获InterruptedException时无法执行此操作。

你的第二个线程会自行中断,但是当它执行时它不会从run()方法返回。

答案 1 :(得分:1)

您中断Thread3_2而不是Thread3_1。

在Thread3_2的run方法中,您正在调用

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");
            }
        }
    }
}

答案 2 :(得分:0)

您正在中断的线程必须设计为通过从run()方法正常退出来处理中断请求。这意味着确保InterruptedExceptions导致代码突破循环。它还意味着在循环内定期检查中断的标志。还有其他一些难以处理的方案,例如不可中断的IO操作。

目标线程将自身重新标记为已中断也是一种很好的做法,因此调用堆栈中的调用者也可以获得中断的指示(在catch语句中使用Thread.currentThread()。interrupt() )。

答案 3 :(得分: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(被中断)中返回

答案 4 :(得分:0)

来自Java教程:

  

许多抛出InterruptedException的方法,例如sleep,都是   旨在取消当前的操作并立即返回   收到一个中断。

     

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

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

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

相关问题