zoukankan      html  css  js  c++  java
  • 线程的Interrupt方法与InterruptedException解析

    1. 线程阻塞状态与等待状态(当一个线程处于被阻塞或等待状态时,它暂时不活动,不允许任何代码且消耗最少的资源)
      • 当一个线程试图获得一个内部的对象锁(而不是java.util.concurrent库中的锁),而该锁被其他线程持有,则该线程进入阻塞状态
      • 当一个线程等待另一个线程通知调度器的一个条件时,它自己进入等待状态。在调用Object.wait方法或Thread.join方法,或者是等待java.util.concurrent库中的Lock或Condition时,就会出现这种情况。实际上被阻塞状态与等待状态是有很大不同的
      • 带有超时参数的方法,调用它们线程会进入计时等待状态。这一状态将一直保持到超时期满或者接收到适合的通知。带有超时的方法有Thread.sleep、Object.wait、Thread.join、Lock.tryLock、Condition.await
    2. 没有强制线程终止的方法。然而Interrupt方法可以用来请求终止线程,当对一个线程调用interrupt方法时,线程的中断状态被置位,这是每一个线程都有的boolean状态,每个线程应该不是的检查这个标志,以判断线程是否被中断。当一个线程的中断状态被置位时,被中断的线程决定如何响应中断
      • intrrupt方法,用来中断线程
      • interrupted是一个静态方法,它检测当前线程是否被中断。而且,该方法会清除该线程的中断状态,重置中断状态为false
      • isInterrupted是一个实例方法,检验是否有线程被中断,不会改变中断状态
    3. 线程中断时抛出InterruptedException异常解析
      • 当一个线程调在sleep方法时,如果在该线程上调用interrupt方法,将抛出异常
      • 当一个线程进入一个同步阻塞( synchronize(o))的等待集wait时,调用interrupt方法,将抛出异常
      • 当线程等待concurrent库中锁Lock时,被中断不抛异常
      • 当线程进入concurrent库中条件等待集await时,被中断不抛异常
      • 如果在中断状态被置位时调用sleep方法,不会休眠,反而会清除这一状态(!)并抛出InterruptException异常
    4. 锁测试与超时
      • tryLock方法试图申请一个锁,在成功获得锁后返回true,否则,立即返回false。而且线程可以离开去做其他事情
        • lock方法不能被中断。如果一个线程在等待获得一个锁时被中断,并不会抛出异常。中断线程在获得锁之前一直处于阻塞状态。如果出现死锁,那么,lock方法就无法终止
        • 然而,如果调用带有超时参数的tryLock(1000,TimeUnit.MILLISECONDS),那么如果线程在等待期间被中断,将会抛出InterruptedException异常。这是一个非常有用的特性,因为允许程序打破死锁
    // 当一个线程调在sleep方法时,如果在该线程上调用interrupt方法
    public class Demo {
           public static void main(String[] args) throws InterruptedException {
                 Thread t = new Thread(new Runnable() {
                        @Override
                        public void run() {
                               try {
                                     Thread.sleep(2000);
                                     System.out.println("end");
                               } catch (InterruptedException e) {
                                     e.printStackTrace();
                               }
                        }
                 });
                 t.start();
                 Thread.sleep(1000);
                 t.interrupt(); // 抛出异常
           }
    }
     
    // 当一个线程进入一个同步阻塞( synchronize(o))的等待集wait时
    public class Demo {
           public Object o = new Object();
           public void fun() throws InterruptedException {
                 synchronized (o) {
                        o.wait();
                 }
           }
           public static void main(String[] args) throws InterruptedException {
                 Demo demo = new Demo();
                 Thread t = new Thread(new Runnable() {
                        @Override
                        public void run() {
                               try {
                                     demo.fun();
                                     System.out.println("end");
                               } catch (InterruptedException e) {
                                     e.printStackTrace();
                               }
                        }
                 });
                 t.start();
                 Thread.sleep(1000);
                 t.interrupt(); // 抛出异常
           }
    }
     
    // 当线程等待concurrent库中锁Lock时
    public class Bank {
           private Lock bankLock;
           private Condition sufficientFunds;
           public Bank() {
                 bankLock = new ReentrantLock();
                 sufficientFunds = bankLock.newCondition();
           }
           public void transfer() throws InterruptedException {
                 bankLock.lock(); // 线程t2不抛出异常,可能发生同步阻塞,建议使用带超时的tryLock(1000,TimeUnit.MILLISECONDS),调用interrupt时抛出异常
    //           if (bankLock.tryLock()) // 线程t2获取不到锁,立即离开做其他事情
    //           if (bankLock.tryLock(3000, TimeUnit.MILLISECONDS)) // 线程t2抛出异常
    //           {
                        try {
                               while (true) {
                               }
                        } finally {
                               bankLock.unlock();
                        }
    //           }
           }
           public static void main(String[] args) throws InterruptedException {
                 Bank bank = new Bank();
                 Thread t1 = new Thread(new Runnable() {
                        @Override
                        public void run() {
                               try {
                                     bank.transfer();
                               } catch (InterruptedException e) {
                                     e.printStackTrace();
                               }
                        }
                 });
                 Thread t2 = new Thread(new Runnable() {
                        @Override
                        public void run() {
                               try {
                                     Thread.sleep(1000);
                                     bank.transfer();
                                     System.out.println("end");
                               } catch (InterruptedException e) {
                                     e.printStackTrace();
                               }
                        }
                 });
                 t1.start();
                 t2.start();
                 Thread.sleep(2000);
                 t2.interrupt();
           }
    }
     
    // 当线程进入concurrent库中条件等待集await时
    public class Bank {
           private Lock bankLock;
           private Condition sufficientFunds;
           public Bank() {
                 bankLock = new ReentrantLock();
                 sufficientFunds = bankLock.newCondition();
                 
           }
           public void transfer(boolean b,boolean c) throws InterruptedException {
                 bankLock.lock();
                 try {
                        if (b)
                               sufficientFunds.await();
                        while (c) {
                               
                        }
                        sufficientFunds.signalAll();
                 } finally {
                        bankLock.unlock();
                 }
           }
           public static void main(String[] args) throws InterruptedException {
                 Bank bank = new Bank();
                 Thread t1 = new Thread(new Runnable() {
                        @Override
                        public void run() {
                               try {
                                     bank.transfer(true,false);
                               } catch (InterruptedException e) {
                                     e.printStackTrace();
                               }
                        }
                 });
                 Thread t2 = new Thread(new Runnable() {
                        @Override
                        public void run() {
                               try {
                                     Thread.sleep(1000);
                                     bank.transfer(false,true);
                                     System.out.println("end");
                               } catch (InterruptedException e) {
                                     e.printStackTrace();
                               }
                        }
                 });
                 t1.start();
                 t2.start();
                 Thread.sleep(2000);
                 t1.interrupt();
           }
    }
    

      

     
     
  • 相关阅读:
    Qt中的QString和QStringList常用方法
    Qt界面编程基本操作
    vs+qt编程相关
    C++的一些关键字用法
    Java学习-hashcode综合练习
    Java学习-HashMap练习
    Java学习-HashSet练习
    Java学习-HashMap性能简单测试
    Java学习-排序二叉树性能简单测试
    java学习-排序二叉树
  • 原文地址:https://www.cnblogs.com/sunxiaoxiaou/p/10539757.html
Copyright © 2011-2022 走看看