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

  • 相关阅读:
    业务决定功能,功能决定技术
    类的设计问题
    鲁棒图的三元素:抽象对象,实体对象和控制对象
    swift 命名空间实现的设计思考:extension YKKit where Base == String
    iOS keychain注解
    学科基本结构理论-布鲁纳学习理论
    软件框架的理解
    数据库管理系统-可扩展的功能组件
    SQLite权威指南
    应用程序员眼中的数据库管理系统:API+数据库语言
  • 原文地址:https://www.cnblogs.com/ixenos/p/6231930.html
Copyright © 2020-2023  润新知