前几篇都介绍了Thread中的几个方法,相信大家都发现一个相似点,那就是sleep,join,wait这样的阻塞方法都必须捕获一个InterruptedException异常,顾名思义就是一个线程中断的异常,那什么是线程中断呢?线程中断会有哪些问题呢?这一篇我们就来介绍一下线程中断的概念:

在java的线程Thread类中有三个方法,比较容易混淆,在这里解释一下

(1)interrupt:置线程的中断状态

(2)isInterrupt:线程是否中断

(3)interrupted:返回线程的上次的中断状态,并清除中断状态



举个例子:

[java] view
plain
copy

  1. class MyThread extends Thread {
  2. ......
  3. ......
  4. public void run() {
  5. try {
  6. while(!Thread.currentThread().isInterrupted()) {  //如果线程没有被中断就继续运行
  7. //阻塞代码:sleep,wait等
  8. //当其他线程,调用此线程的interrupt()方法时,会给此线程设置一个中断标志
  9. //sleep,wait等方法会检测这个标志位,同时会抛出InterruptedException,并清除线程的中断标志
  10. //因此在异常段调用Thread.currentThread().isInterrupted()返回为false
  11. }
  12. } catch (InterruptedException e) {
  13. //由于阻塞库函数,如:Object.wait,Thread.sleep除了抛出异常外,还会清除线程中断状态,因此可能在这里要保留线程的中断状态
  14. Thread.currentThread().interrupt();//从新设置线程的中断标志
  15. }
  16. }
  17. public void cancel() {
  18. interrupt();  //中断线程
  19. }
  20. }

外部调用

[java] view
plain
copy

  1. MyThread thread = new MyThread();
  2. thread.start(); //开启线程
  3. ......
  4. thread.cancel();  //中断线程
  5. System.out.println(thread.isInterrupt)//打印线程中断标志

一般来说,阻塞函数,如:Thread.sleep、Thread.join、Object.wait等在检查到线程的中断状态时,会抛出InterruptedException,同时会清除线程的中断状态



对于InterruptedException的处理,可以有两种情况:

(1)外层代码可以处理这个异常,直接抛出这个异常即可

(2)如果不能抛出这个异常,比如在run()方法内,因为在得到这个异常的同时,线程的中断状态已经被清除了,需要保留线程的中断状态,则需要调用Thread.currentThread().interrupt()



另外,Thread.interrupted()在jdk库的源代码中比较常用,因为它既可以得到上一次线程的中断标志值,又可以同时清除线程的中断标志,一举两得,但同时也有坏处,就是这个函数有清除中断状态的副作用,不容易理解。

从上面的分析可以查出,通过中断机制也可以实现线程的终止,但是这种方式也是基于抛出异常的,所以这种方式也是不安全的,同时我们也可以这样理解就是中断机制就是来结束那些阻塞的线程的,因为阻塞线程回去检查中断标志位,又中断就抛异常来结束线程的运行。

通过这一篇貌似可以理解那些调用阻塞线程的方法为什么要抛出中断异常了,同时也理解了线程的中断机制。

好吧,又结束了一篇,但是这一篇不是最后一篇奥,千万不要放弃呀,后面还有呢!要继续关注呀!

Java中的线程Thread方法之---interrupt()的更多相关文章

  1. Java中的线程Thread方法之---suspend()和resume()

    前篇说到了Thread中的join方法,这一篇我们就来介绍一下suspend()和resume()方法,从字面意义上可以了解到这两个方法是一对的,suspend()方法就是将一个线程挂起(暂停),re ...

  2. Java中的线程Thread方法之---stop()

    搞过Java线程的人都知道,stop这个方法是臭名昭著了,早就被弃用了,但是现在任然有很多钟情与他的人,永远都放不下他,因为从他的字面意思上我们可以知道他貌似可以停止一个线程,这个需求是每个搞线程开发 ...

  3. Java中的线程Thread方法之---join()

    上一篇我们说到了Thread中的stop方法,这一篇我们再来看一下方法join的使用,那么方法Join是干啥用的? 简单回答,同步,如何同步? 怎么实现的? 下面将逐个回答. join方法从字面上的意 ...

  4. Java中的线程Thread总结

    首先来看一张图,下面这张图很清晰的说明了线程的状态与Thread中的各个方法之间的关系,很经典的! 在Java中创建线程有两种方法:使用Thread类和使用Runnable接口. 要注意的是Threa ...

  5. Java中实现线程的方法

    Java中有几种方法可以实现一个线程?用什么关键字修饰同步方法?stop()和suspend()方法为何不推荐使用? 第一种:继承Thread类 new Thread(){}.start();这表示调 ...

  6. Java 中的线程 thread

    一.问:线程有哪些状态? new, runnable, running, waiting, dead 线程状态间的流转 二.问:线程实现方式? 实现 Runnable 接口,然后new Thread, ...

  7. 【Java中的线程】java.lang.Thread 类分析

    进程和线程 联想一下现实生活中的例子--烧开水,烧开水时是不是不需要在旁边守着,交给热水机完成,烧开水这段时间可以去干一点其他的事情,例如将衣服丢到洗衣机中洗衣服.这样开水烧完,衣服洗的也差不多了.这 ...

  8. JAVA中创建线程的三种方法及比较

    JAVA中创建线程的方式有三种,各有优缺点,具体如下: 一.继承Thread类来创建线程 1.创建一个任务类,继承Thread线程类,因为Thread类已经实现了Runnable接口,然后重写run( ...

  9. JAVA中创建线程池的五种方法及比较

    之前写过JAVA中创建线程的三种方法及比较.这次来说说线程池. JAVA中创建线程池主要有两类方法,一类是通过Executors工厂类提供的方法,该类提供了4种不同的线程池可供使用.另一类是通过Thr ...

随机推荐

  1. 使用Gradle发布项目到JCenter仓库 (转载)

    原文:使用Gradle发布项目到JCenter仓库 这篇文章介绍通过Gradle把开源项目发布到公共仓库JCenter中,方便你我他的事情,我们都是很懒的嘛.JCenter现在是Android Stu ...

  2. Java对象什么时候可以被垃圾回收?JVM的永久代中会发生垃圾回收么?

    当对象对当前使用这个对象的应用程序变得不可触及的时候,这个对象就可以被回收了.垃圾回收不会发生在永久代,如果永久代满了或者是超过了临界值,会触发完全垃圾回收(Full GC).如果你仔细查看垃圾收集器 ...

  3. leetcood学习笔记-28-KMP*

    题目: 第一次提交: class Solution: def strStr(self, haystack: str, needle: str) -> int: if not len(needle ...

  4. Ubuntu下终端命令安装sublime

    Ubuntu下终端命令安装sublime出现软件包无法定位 sublime-text-install 且多次换源不成功 建议采用离线安装 安装教程如下 用Ubuntu上的浏览器下载一个 Sublime ...

  5. php手册的一些思考

    函数手册一定要认真看,很多用法都不太清楚:   array array_merge ( array $array1 [, array $... ] ) array_merge() 将一个或多个数组的单 ...

  6. js——private 私有方法公有化

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  7. LInux多线程编程----线程特定数据的处理函数

    1.pthread_key_t和pthread_key_create() 线程中特有的线程存储, Thread Specific Data .线程存储有什么用了?他是什么意思了?大家都知道,在多线程程 ...

  8. 关于ACL访问控制的一些问题:AntiACL

    @echo off title AntiACL Made By gwsbhqt color 0a reg query "HKU\S-1-5-19" >nul 2>nul ...

  9. 数据挖掘Aprior算法详解及c++源码

    [算法大致描述] Aprior算法主要有两个操作,扫描数据库+统计.计算每一阶频繁项集都要扫描一次数据库并且统计出满足支持度的n阶项集. [算法主要步骤] 一.频繁一项集 算法开始第一步,通过扫描数据 ...

  10. 剑指offer——41数组中出现次数超过一半的数字

    题目描述 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2. ...