Java 并发 中断线程

Java 并发 中断线程

@author ixenos 

 

 

对Runnable.run()方法的三种处置情况


 

1.在Runnable.run()方法的中间中断它

2.等待该方法到达对cancel标志的测试(用一个if+标志变量)

3.等待该方法到达程序员准备好离开的地方

 

  第一种情况比其他两种难以处置,因为当打断一个被阻塞的任务时,可能需要清理资源。

  因此,在任务的run()方法中间打断,就像是抛出的异常,在“catch异常处理”中清理资源(否则不放锁),于是Java也为这种打断使用了异常机制。

 

 

可中断阻塞和不可中断阻塞


 

1.SleepBlock 是可中断的阻塞

2.IOBlocked 和 SynchronizedBlocked 是不可中断的阻塞(I/O和synchronized方法都不需要InterruptedException处理器)

 

示例:

  1 // Interrupting a blocked thread.
  2 import java.util.concurrent.*;
  3 import java.io.*;
  4 import static net.mindview.util.Print.*;
  5 
  6 /*
  7     SleepBlock
  8 
  9 */
 10 class SleepBlocked implements Runnable {
 11   public void run() {
 12     try {
 13       TimeUnit.SECONDS.sleep(100);
 14     } catch(InterruptedException e) {
 15       print("InterruptedException");
 16     }
 17     print("Exiting SleepBlocked.run()");
 18   }
 19 }
 20 
 21 
 22 /*
 23     IOBlock
 24 */
 25 class IOBlocked implements Runnable {
 26   private InputStream in;
 27   public IOBlocked(InputStream is) { in = is; }
 28   public void run() {
 29     try {
 30       print("Waiting for read():");
 31       in.read();
 32     } catch(IOException e) {
 33       if(Thread.currentThread().isInterrupted()) {
 34         print("Interrupted from blocked I/O");
 35       } else {
 36         throw new RuntimeException(e);
 37       }
 38     }
 39     print("Exiting IOBlocked.run()");
 40   }
 41 }
 42 
 43 
 44 /*
 45       SynchronizedBlock
 46 
 47 */
 48 class SynchronizedBlocked implements Runnable {
 49   public synchronized void f() {
 50     while(true) // Never releases lock
 51       Thread.yield();
 52   }
 53   public SynchronizedBlocked() {
 54     new Thread() {
 55       public void run() {
 56         f(); // Lock acquired by this thread
 57       }
 58     }.start();
 59   }
 60   public void run() {
 61     print("Trying to call f()");
 62     f();
 63     print("Exiting SynchronizedBlocked.run()");
 64   }
 65 }
 66 
 67 
 68 public class Interrupting {
 69   //用java.util.concurrent.*包中的Executor来统一管理多个线程
 70   private static ExecutorService exec =
 71     Executors.newCachedThreadPool();
 72 
 73   static void test(Runnable r) throws InterruptedException{
 74     /*
 75           submit() 启动任务将返回Future<?>,
 76           可以调用cancel来调用interrupt方法中断某个特定任务;
 77           executor() 启动任务,
 78           只能调用shutdownNow()来中断所有任务。
 79     */
 80     Future<?> f = exec.submit(r);
 81     TimeUnit.MILLISECONDS.sleep(100);
 82     print("Interrupting " + r.getClass().getName());
 83 
 84     
 85     f.cancel(true); // Interrupts if running
 86     print("Interrupt sent to " + r.getClass().getName());
 87   }
 88 
 89   //main方法
 90   public static void main(String[] args) throws Exception {
 91     test(new SleepBlocked());
 92     test(new IOBlocked(System.in));
 93     test(new SynchronizedBlocked());
 94     TimeUnit.SECONDS.sleep(3);
 95     print("Aborting with System.exit(0)");
 96     System.exit(0); // ... since last 2 interrupts failed
 97   }
 98 } /* Output: (95% match)
 99 Interrupting SleepBlocked
100 InterruptedException
101 Exiting SleepBlocked.run()
102 Interrupt sent to SleepBlocked
103 Waiting for read():
104 Interrupting IOBlocked
105 Interrupt sent to IOBlocked
106 Trying to call f()
107 Interrupting SynchronizedBlocked
108 Interrupt sent to SynchronizedBlocked
109 Aborting with System.exit(0)
110 *///:~

 

 

中断线程


1.Thread类包含interrupt()方法,可以终止被阻塞的任务,这个方法将设置线程的中断状态

  1)如果一个线程已被阻塞 或 试图执行一个阻塞操作时,调用interrupt设置这个线程的中断状态,将抛出InterruptedException

  2)当抛出InterruptedException 或 该任务调用Thread.interrupted()时,中断状态将被复位为 false (但实际已中断~)。

      • 可见,使用Thread.interrupted() 既离开run()循环 中断线程,又不抛出InterruptedException

2.中断状态:中断状态是每一个线程都具有的boolean标志,(建议每个线程都应该不时地检查这个标志,以判断线程是否被中断)

  1)t.interrupt(): 当对一个线程调用interrupt()方法时,线程的中断状态将被置位

  2)Thread.interrupted(): 

 

posted @ 2017-01-12 15:59  ixenos  阅读(350)  评论(0编辑  收藏  举报