2015-08-08 63 views
3

我正在尝试学习线程中断以及如何在不调用stop的情况下使线程终止。如何用线程中断方法停止线程

public class Test implements Runnable{ 
     static Thread threadTest=null; 
     public static void main(String args[]){ 
      System.out.println("Hello i am main thread"); 
      Test thread= new Test(); 
      threadTest= new Thread(thread); 
      threadTest.start(); 
} 

private static void exitThread() { 
    threadTest.interrupt(); 
} 

@Override 
public void run() { 
    boolean run = true; 
    while (run) { 
     try { 
      System.out.println("Sleeping"); 
      Thread.sleep((long) 10000); 
      exitThread(); 
      System.out.println("Processing"); 

     } catch (InterruptedException e) { 

      run = false; 
     } 
    } 

} 


} 

输出

Hello i am main thread 

Sleeping 

Processing 

Sleeping 

我无法理解为什么睡觉打印第二次打断异常被抛出,而不是第一再寄一次检查了下volatile关键字用来帖子第二次停止java.but中的线程,但我无法理解在这种情况下如何使用该线程,因为线程被中断停止。

回答

3

为了看到线程被中断,而不是进入休眠方法的第二时间,改变while循环测试在运行方法来检查中断标志:

@Override 
public void run() { 
    while (!Thread.currentThread().isInterrupted()) { 
     try { 
      System.out.println("Sleeping"); 
      Thread.sleep((long) 10000); 
      exitThread(); 
      System.out.println("Processing"); 
     } catch (InterruptedException e) { 
      Thread.currentThread().interrupt(); 
     } 
    } 
} 

线程将休眠状态,然后设置自己的中断标志,然后检查标志并终止。只有在设置中断标志时线程处于休眠状态时,Thread#sleep方法才会抛出InterruptedException。

您的本地布尔变量是不需要的。如果Thread#sleep引发一个InterruptedException异常(在本例中不会因为线程检查中断标志而离开while循环),那么中断标志将被清除,将其恢复到catch块允许while测试看到线程中断。

在实际的程序中,线程会被另一个线程中断,没有理由让线程自行中断(取而代之)。

1

调用Thread.interrupt()只是为该线程设置了一个标志。它什么都不做。只有阻塞方法(通常是声明throws InterruptedException)会响应正在设置的标志(通过抛出)。该标志是粘性因为它保持设置直到它被清除。

因此,第一次调用sleep方法正常运行(中断标志还没有设置)。在那之后,你的代码没有做任何事情作用于被中断的状态,直到第二次循环迭代,其中睡眠呼叫检测到中断状态并抛出异常。

您可以随时使用Thread.interrupted()或Thread.isInterrupted()检查中断状态(注意,如果已设置,中断()也会清除中断状态)。

1

在这里你创建另一个线程测试类,但“主”都有自己的线程,让你创建新的线程进行解释。 在此代码中您正在中断新创建的线程线程-0不是主线程,当您执行此代码时,它正在使线程在它进入方法睡眠之前exitThread(),因此它正在显示处理,但如果你试图把线程睡眠输入了ExitThread(后),你将有你的答案 如在此代码:

公共类测试实现Runnable { 公共布尔运行= TRUE;

@Override 
public void run() { 
    while (run) { 

     try { 
      System.out.println("Sleeping..."); 
      exitThread(); 
      Thread.sleep(10000); 
      System.out.println("Processing..."); 
     } catch (InterruptedException e) { 
      System.out.println("Thread intreputted " + e); 
      run = false; 
     } 
    } 
} 

private void exitThread() { 
    Thread.currentThread().interrupt(); 
    if (Thread.currentThread().isInterrupted()) 
     System.out.println(Thread.currentThread().getName() 
       + " is intreputted"); 
    else 
     System.out.println("alive"); 
} 

public static void main(String[] args) { 
    System.out.println("hi I am current thread------>" 
      + Thread.currentThread().getName()); 
    Test test = new Test(); 
    Thread thread = new Thread(test); 
    thread.start(); 
} 

}

希望这将是有益的