[读书笔记[CoreJava2AdvancedFeatures][多线程]1.2中断线程



线程将在它的run方法返回时终止。在JDK1.0中,还存在一个stop方法,其它线程可以调用它来终止线程。不过这个方法现在已经被弃用了。我们将会在后面[线程安全的集合]给出解释。

尽管现在已经没有 强制 终止线程的方法了,但是你还是可以用interrupt方法来 请求 终止一个线程。

当interrupt方法在一个线程上被调用时,该线程的 中断状态 将会被置位。这是一个布尔类型的标志,存在于每一个线程之中。每个线程都应该不时地检查这个标志,以判断线程是否应该被中断。

为了查明中断状态是否被置位了,需要首先调用静态的Thread.currentThread方法来取得当前线程,然后调用它的isInterrupted方法:

while(!Thread.currentThread().isInterrupted()&& more work to do){
  do more work
}

尽管如此,如果一个线程被阻塞了,他就无法检查中断状态了。这就是产生InterruptedException异常的地方。当在一个被阻塞的线呈上调用interrupt方法时,阻塞调用就会被InterruptedException异常所终止。


没有任何语言方面的需求要求一个被中断的线程应该终止。中断一个线程只是为了引起该线程的注意,被中断线程可以决定应该如何应对中断。某些线程非常重要,以至于他们应该不理会中断,而是在处理完抛出的异常之后继续执行。但是更普遍的情况是,一个线程将把中断看作一个终止请求。这种线程的run方法遵循如下的形式:

public void run(){

     try{
        ...
        while(!Thread.currentThread().isInterrupted() && more work to do)
       {

             do more work
        }

     }
     catch(InterruptedException e)
     {
      // thread was interrupted during sleep or wait
     }
     finally
     {
         cleanup, if required
     }

     //exiting the run method terminates the thread
}

如果你在每次工作迭代之后都调用sleep方法,那么这个isInterrupted检查就不是必须的。如果你在中断状态被置位时调用sleep方法,那么sleep方法将抛出一个InterruptedException异常。因此,如果你循环调用sleep,就要花点心思检查中断状态并捕获InterruptedException异常。这样的run方法的形式如下所示:
public void run()
{
  try{
      ...
      while(more work to do)
      {
          do more work
          Thread.sleep(delay);
      }
  }
  catch(InterruptedException e)
  {
       //thread was interrupted during sleep or wait
  }
  finally
  {
      cleanup, if required
  }
// exiting the run method terminates the thread
}

警告:当sleep方法抛出一个InterruptedException异常时,它同时也会清除中断状态。

注意:有两个非常类似的方法,interrupted 和 isInterrupted。interrupted方法是一个静态方法,它检查当前线程是否已被中断。而且调用interrupted方法会清除该线程的中断状态。另一方面,isInterrupted方法是一个实例方法,可以用它来检查是否有线程已被中断了。调用它不会改变中断状态的值。

你会在很多发布的代码中发现InterruptedException异常被抑制在了一个很低的层次上,就像这样:
void mySubTask(){
...
try{sleep(delay);}
catch(InterruptedException e){} //Don't IGNORE!
...
}

不要这样做!如果你不能很好地在catch子句中处理异常,那么你还有两个合理的选择:
1)在catch子句中,调用Thread.currentThread().interrupt()来设置中断状态。然后调用这可以对其进行测试:

void mySubTask()
{
  ...
try{sleep(delay);}
catch(InterruptedException e){ Thread.currentThread().interrupt();}
...
}


2)或者更好的选择是,标记你的方法将抛出InterruptedExcetpion异常,不采用try语句块捕获异常。那么调用这(或者,最终的run方法)就能够捕获该异常。
void mySubTask() throws InterruptedException
{
...
sleep(delay);
...
}


  API java.lang.Thread 1.0

  • void interrupt() 发送一个中断请求给线程。这个线程的中断线程将被设为True。如果这个线程当前被一个sleep调用阻塞,那么将抛出一个InterruptedException异常。
  • static boolean interrupted() 检查当前线程(即正在执行该指令的线程)是否已经被中断了。注意,这是一个静态方法。对他的调用会产生副作用,它会将当前线程的中断状态设成false。
  • boolean isInterrupted() 检查一个线程是否已经被终止了。与static interrupted方法不同,这个调用不会改变线程的中断状态。
  • static Thread currentThread() 返回代表当前执行线程的Thread对象。

你可能感兴趣的:(jdk,thread,多线程,api,读书,delay)