浅析java线程中断的办法


Posted in Javascript onJuly 29, 2018

中断线程相关的方法

中断线程有一些相应的方法,这里列出来一下。

注意,如果是Thread.method(),则代表是静态方法。如果是thread.method()则代表着是类方法

void thread.stop()

这个方法能中断正在运行的线程,但是已经不推荐使用了,在将来的版本或许弃用,因为强行中断运行中的线程,是不安全的。

void thread.interrupt()

如果正在运行wait(),sleep(),join()这三个方法阻塞了线程,那么将会使得线程抛出InterruptedException异常,这是一个中断阻塞的过程。如果是其它的正在运行的状态,那么将不会有任何影响,也不会中断线程,或者抛出异常,只会会打上一个中断线程的标志,是否中断线程,将由程序控制。

boolean thread.isInterrupted()

它会获取当前线程的标志,如果之前调用过thread.interrupt(),那么它的返回值是true。它的作用就是返回该线程是否有中断标志。多次调用这个方法的结果是一样的。

void Thread.interrupted()

与前面的方法不一样的是,这是一个静态方法,代表着不需要拿到线程对象就可以直接执行,所以它的作用是返回当前线程是否有中断标志。但是它的区别是,当调用这个方法之后,会清除程序的中断标志,就是如果当前线程已中断,第一次调用这个方法的返回值是true,第二次调用这个方法的返回值为false,因为调用方法时,会清除它的中断标志。

中断线程

for循环标记退出

package com.xiaojiezhu.thread;

/**
 * @author xiaojie.zhu
 */
public class ThreadBreak implements Runnable {

  @Override
  public void run() {
    for(int i = 0 ; i < 10000 ; i ++){
      boolean interruped = Thread.currentThread().isInterrupted();
      if(interruped){
        //有中断标记,中断
        break;
      }
      System.out.println(i);
    }

    System.out.println("over");
  }


  public static void main(String[] args) throws InterruptedException {
    Thread t = new Thread(new ThreadBreak());
    t.start();
    Thread.sleep(1);

    t.interrupt();
  }
}

打印结果如下

44
45
46
47
over

阻塞的退出线程

只要是在运行wait(),sleep(),join()的方法,它就会声明一个InterruptedException异常,也就是意味着这些方法并不是一定能执行完成,因为当调用线程的interrupt()方法时,就会中断这个阻塞的办法,从而进入到异常中,代码如下

package com.xiaojiezhu.thread;

/**
 * @author xiaojie.zhu
 */
public class ThreadBreak2 implements Runnable {
  @Override
  public void run() {
    try {
      Thread.sleep(20000);
      System.out.println("这段话不会输出");
    } catch (InterruptedException e) {
      //如果在sleep()的过程中调用了interrupt()方法,就会进入这里,因为会强行中断sleep()
      
      //这里打印出来的中断标记为false,因为只要进入了InterruptedException异常,中断标记就会被清除掉
      System.out.println("中断标记为:" + Thread.currentThread().isInterrupted());
      System.out.println("输出异常");
      e.printStackTrace();
    }
  }

  public static void main(String[] args) throws InterruptedException {
    Thread t = new Thread(new ThreadBreak2());
    t.start();

    Thread.sleep(100);

    t.interrupt();

    System.out.println("over");
  }
}

打印结果如下

over
中断标记为:false
输出异常
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at com.xiaojiezhu.thread.ThreadBreak2.run(ThreadBreak2.java:10)
at java.lang.Thread.run(Thread.java:748)

注意:因为只要进入了InterruptedException异常,中断标记就会被清除掉

这里会衍生出另一种情况,就是如果在进入阻塞方法之前,就有了中断标记呢?会发生什么,就如下的代码:

for(int i = 0 ; i < 10000 ; i ++){
  System.out.println(i);
}
try {
  System.out.println("开始sleep");
  Thread.sleep(20000);
  System.out.println("结束sleep");

} catch (InterruptedException e) {
  e.printStackTrace();
}

实际上它会先执行完上面的for循环,因为for循环中是无法中止的,在进入sleep()的时候,瞬间就抛出异常

完整的测试代码如下

package com.xiaojiezhu.thread;

/**
 * @author xiaojie.zhu
 */
public class ThreadBreak3 implements Runnable {

  @Override
  public void run() {
    for(int i = 0 ; i < 10000 ; i ++){
      System.out.println(i);
    }
    try {
      System.out.println("开始sleep");
      Thread.sleep(20000);
      System.out.println("结束sleep");

    } catch (InterruptedException e) {
      e.printStackTrace();
    }

  }

  public static void main(String[] args) {
    Thread thread = new Thread(new ThreadBreak3());
    thread.start();

    thread.interrupt();
  }
}

打印结果如下

9997
9998
9999
开始sleep
java.lang.InterruptedException: sleep interrupted
  at java.lang.Thread.sleep(Native Method)
  at com.xiaojiezhu.thread.ThreadBreak3.run(ThreadBreak3.java:15)
  at java.lang.Thread.run(Thread.java:748)

使用stop()方法停止线程

thread.stop()方法是一个不安全的方法,已经不推荐使用了,但是在目前的代码中,还能正常使用,我们不推荐这样使用,但是这里介绍一下

package com.xiaojiezhu.thread;

/**
 * @author xiaojie.zhu
 */
public class ThreadBreak4 implements Runnable {
  @Override
  public void run() {
    System.out.println("进入线程");
    try {
      Thread.sleep(20000);
      System.out.println("结束线程");
    } catch (InterruptedException e) {
      e.printStackTrace();
    }

  }

  public static void main(String[] args) {
    Thread t = new Thread(new ThreadBreak4());
    t.start();
    try {
      Thread.sleep(200);

      t.stop();

      System.out.println("over");
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
  }
}

打印结果如下

进入线程
over

Javascript 相关文章推荐
JavaScript去掉数组中的重复元素
Jan 13 Javascript
基于jquery的代码显示区域自动拉长效果
Dec 07 Javascript
js操作IE浏览器弹出浏览文件夹可以返回目录路径
Jul 14 Javascript
javascript正则表达式使用replace()替换手机号的方法
Jan 19 Javascript
angular实现商品筛选功能
Feb 01 Javascript
node.js中fs.stat与fs.fstat的区别详解
Jun 01 Javascript
JavaScript判断变量名是否存在数组中的实例
Dec 28 Javascript
基于jQuery实现的设置文本区域的光标位置
Jun 15 jQuery
在Create React App中启用Sass和Less的方法示例
Jan 16 Javascript
在vue中利用v-html按分号将文本换行的例子
Nov 14 Javascript
Vuex的热更替如何实现
Jun 05 Javascript
vue项目中播放rtmp视频文件流的方法
Sep 17 Javascript
还不懂递归?读完这篇文章保证你会懂
Jul 29 #Javascript
如何在js代码中消灭for循环实例详解
Jul 29 #Javascript
Vue-cli3项目配置Vue.config.js实战记录
Jul 29 #Javascript
vue权限路由实现的方法示例总结
Jul 29 #Javascript
JS高级技巧(简洁版)
Jul 29 #Javascript
js运算符的一些特殊用法
Jul 29 #Javascript
不得不知的ES6小技巧
Jul 28 #Javascript
You might like
文章推荐系统(二)
2006/10/09 PHP
一个取得文件扩展名的函数
2006/10/09 PHP
php中DOMDocument简单用法示例代码(XML创建、添加、删除、修改)
2010/12/19 PHP
Php图像处理类代码分享
2012/01/19 PHP
PDO版本问题 Invalid parameter number: no parameters were bound
2013/01/06 PHP
php去除html标记的原生函数详解
2015/01/27 PHP
Laravel中使用阿里云OSS Composer包分享
2015/02/10 PHP
使用PHP uniqid函数生成唯一ID
2015/11/18 PHP
PHP使用PDO操作sqlite数据库应用案例
2019/03/07 PHP
使用简洁的jQuery方法实现隔行换色功能
2014/01/02 Javascript
jquery判断复选框选中状态以及区分attr和prop
2015/12/18 Javascript
DOM操作原生js 的bug,使用jQuery 可以消除的解决方法
2016/09/04 Javascript
html中鼠标滚轮事件onmousewheel的处理方法
2016/11/11 Javascript
Vue单页式应用(Hash模式下)实现微信分享的实例
2017/07/21 Javascript
Vue打包后出现一些map文件的解决方法
2018/02/13 Javascript
vue项目国际化vue-i18n的安装使用教程
2018/03/14 Javascript
前端js中的事件循环eventloop机制详解
2019/05/15 Javascript
深入浅析Vue中mixin和extend的区别和使用场景
2019/08/01 Javascript
微信小程序背景音乐开发详解
2019/12/12 Javascript
jQuery 隐藏/显示效果函数用法实例分析
2020/05/20 jQuery
[02:22]2018DOTA2亚洲邀请赛VG赛前采访
2018/04/03 DOTA
python二分法实现实例
2013/11/21 Python
python使用插值法画出平滑曲线
2018/12/15 Python
如何利用Anaconda配置简单的Python环境
2019/06/24 Python
在交互式环境中执行Python程序过程详解
2019/07/12 Python
python数据库编程 ODBC方式实现通讯录
2020/03/27 Python
matplotlib 曲线图 和 折线图 plt.plot()实例
2020/04/17 Python
Python 多线程C段扫描、检测 Ping扫描脚本的实现
2020/09/03 Python
浅析python字符串前加r、f、u、l 的区别
2021/01/24 Python
巧用CSS3的calc()宽度计算做响应模式布局的方法
2018/03/22 HTML / CSS
HTML5中的postMessage API基本使用教程
2016/05/20 HTML / CSS
大学军训自我鉴定
2013/12/15 职场文书
大学生活自我评价
2014/04/09 职场文书
全陪导游词
2015/02/04 职场文书
毕业生登记表班级意见
2015/06/05 职场文书
2015大学生暑期实习报告
2015/07/13 职场文书