并发编程(二)----线程的中断

线程中断

线程中断的概念

疑问:杀毒软件没完成时,点击取消按钮,杀毒软件立刻就会退出吗?
错误理解:被中断的线程立刻退出

概念

  • 1.java中线程中断是一种协作机制

  • 2.通过中断并不能直接终止线程的运行

  • 3.需要被中断的线程自己处理中断
    例:父母叮嘱在外孩子注意身体,但是是否注意身体,完全取决于孩子

  • 每个线程有一个boolean类型的标志位,代表线程是否中断

  • 线程1想中断线程2,线程1只需要设置线程2的中断标识为true

  • 线程2在合适的时候处理中断请求,甚至线程2可以选择不处理中断请求

线程中断相关方法

  • 1.public static boolean interrupted()
    测试当前线程是否中断,线程的中断状态由该方法清除。
    如果连续两次调用该方法,则第二次调用将返回false。
    在第一次调用已清除了其中断状态之后,且第二次调用检验完中断状态前
    可以对当前线程再次中断
  • 2.public boolean isInterrupted()
    测试线程是否已经中断,线程的中断不受该方法影响
  • 3.public void interrupt()
    将调用该方法的对象所表示的线程标记一个停止标记,并不是真正停止该线程
    intertupt()是唯一能将中断状态设置为true的方法,interrupted()会将中断状态清除

中断的处理

  • 1.方法声明中有抛出InterruptedException则表示该方法是可中断的
  • 2.常见的抛出InterruptedException异常的方法:
    a.Object.wait()
    b.Thread.sleep()
    c.BlockQueue.put()
    d.BlockQueue.take()
  • 3.java中只能设置线程的中断状态,那被中断的线程应该做什么?
    视情况而定
    可以立即终止,或者执行完再终止
    如果不确定调用interrupt()后该线程会做出什么样的响应,那就不应该中断该线程

抛出InterruptedException

如果抛出InterruptedException意味着一个方法是阻塞方法,
那么调用一个阻塞方法意味着你的方法也是一个阻塞方法
通常最容易的策略是自己抛出InterruptedException

package com.hexy.thread.demo;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

/***
* 任务队列,封装了LinkedBlockingQueue
*/
public class ThreadDemo4<T> {
   private static final int MAX_TASKS  = 1000;

   private BlockingQueue<T> queue = new LinkedBlockingQueue<>(MAX_TASKS);

   public void putTask(T t)throws InterruptedException{
       queue.put(t);
   }

   public T getTask()throws  InterruptedException{
       return queue.take();
   }
}

## 中断的响应

捕获异常再抛出

有时候需要在传播异常之前进行一些清理工作,
这种情况下看,可以捕获InterruptedException,执行清理,然后抛出异常

package com.hexy.thread.demo;

/**
* 捕获中断异常并抛出
*/
public class ThreadDemo5 {
   public static void main(String[] args) throws InterruptedException{
       Thread thread = Thread.currentThread();
       try {
           thread.interrupt();
           Thread.sleep(3000);
       }catch (InterruptedException e){
           //做一些清理工作
           System.out.println("做一些清理工作");
           throw e;
       }
   }
}

重新中断

  • 有时候代码里直接抛出InterruptedException不合适
  • 如Runnable借口的run()方法不允许抛出异常
  • 如果线程运行中出现了InterruptedException,又不能抛出异常
  • 直接捕获异常,可能又没办法通知上层代码,又不能保留中断的证据
  • 比价好的方式是再次调用interrupt()方法重新中断
package com.hexy.thread.demo;

/**
 * 重新设置中断
 */
public class ThreadDemo6 extends Thread {
    public static void main(String[] args) throws InterruptedException {
        Thread thread = new ThreadDemo6();
        System.out.println("starting thread");
        thread.start();
        Thread.sleep(3000);
        System.out.println("asking thread to sleep");
        thread.interrupt();
        Thread.sleep(3000);
        System.out.println("stopping application");
    }

    @Override
    public void run(){
        while(!Thread.currentThread().isInterrupted()){
            //循环等待线程中断
            System.out.println("Thread Running");
            try {
                //应该会执行3次
                //线程阻塞,如果线程收到中断操作信号将抛出异常
                Thread.sleep(1000);
            }catch (InterruptedException e){
                System.out.println("thread interrupted..");
                //false
                System.out.println(this.isInterrupted());
                //中不中断由自己决定,如果需要真的中断线程,则需要重新设置中断位
                //如果不需要则不调用
                Thread.currentThread().interrupt();
            }
        }
        System.out.println("interrupted ... "+this.isInterrupted());
        System.out.println("thread exiting");
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值