当前位置: 首页 > news >正文

java取消线程实例

本文展示一个常见的取消线程的方法。

错误实例

class BrokenPrimeProducer extends Thread {
    private final BlockingQueue<BigInteger> queue;
    private volatile boolean cancelled = false;

    BrokenPrimeProducer(BlockingQueue<BigInteger> queue) {
        this.queue = queue;
    }

    public void run() {
        try {
            BigInteger p = BigInteger.ONE;
            while (!cancelled){
                queue.put(p = p.nextProbablePrime());
            }    
        } catch (InterruptedException consumed) {
        }
    }

    public void cancel() {
        cancelled = true;
    }
}

这里试图用一个标志来跳出while循环,理论上貌似可行,但是这里使用的是阻塞的操作,那么就出现一种场景,线程永远阻塞在put方法,根本就没来得及下个循环去判断cancelled这个条件,造成永远无法停止掉线程。

正确方法

通过中断来取消线程。

public class PrimeProducer extends Thread {
    private final BlockingQueue<BigInteger> queue;

    PrimeProducer(BlockingQueue<BigInteger> queue) {
        this.queue = queue;
    }

    public void run() {
        try {
            BigInteger p = BigInteger.ONE;
            while (!Thread.currentThread().isInterrupted()){
                queue.put(p = p.nextProbablePrime());
            }    
        } catch (InterruptedException consumed) {
            /* Allow thread to exit */
        }
    }

    public void cancel() {
        interrupt();
    }
}

这里的关键是queue的put操作能够响应interrupt方法,抛出InterruptedException,倒不是因为while条件里头的isInterrupted,这里while条件换成boolean可以照样可以。

小结

调用interrupt并不意味着立即停止目标线程正在进行的工作,而只是传递了请求中断的消息。对中断操作的正确理解是:它并不会真正地中断一个正在运行的线程,而只是发出中断请求,然后由线程在下一个合适的时刻中断自己。

有些方法,例如wait、sleep和join等,将严格地处理这种请求,当它们收到中断请求或者在开始执行时发现某个已被设置好的中断状态时,将抛出一个异常。设计良好的方法可以完全忽略这种请求,只要它们能使调用代码对中断请求进行某种处理。

设计糟糕的方法可能会屏蔽中断请求,从而导致调用栈中的其他代码无法对中断请求作出响应。在使用静态的interrupted时应该小心,因为它会清除当前线程的中断状态。如果在调用interrupted时返回了true,那么除非你想屏蔽这个中断,否则必须对它进行处理—可以抛出InterruptedException,或者通过再次调用interrupt来恢复中断状态。

相关文章:

  • JqGrid
  • 【React系列】如何构建React应用程序
  • 【逻辑题】舅舅问题
  • 如何开发主控台部件
  • 优秀网站分享
  • 工具收藏
  • MongoDB 学习笔记之 WriteConcern
  • js new Date()的兼容性问题
  • Jedox Cloud安全可升级自助式商业情报
  • [bzoj1006]: [HNOI2008]神奇的国度(最大势算法)
  • 由插件封装引出的一丢丢思考
  • 背水一战 Windows 10 (53) - 控件(集合类): ItemsControl 的布局控件 - ItemsStackPanel, ItemsWrapGrid...
  • 三网卡服务器 配置三线三IP linux策略路由
  • Oracle 插入时间时 报错:ORA-01861: 文字与格式字符串不匹配 的解决办法
  • Entity Framework中的字符串插值引发担忧
  • [Vue CLI 3] 配置解析之 css.extract
  • 【译】理解JavaScript:new 关键字
  • 【跃迁之路】【519天】程序员高效学习方法论探索系列(实验阶段276-2018.07.09)...
  • emacs初体验
  • Java小白进阶笔记(3)-初级面向对象
  • js递归,无限分级树形折叠菜单
  • js正则,这点儿就够用了
  • Laravel Telescope:优雅的应用调试工具
  • Linux快速复制或删除大量小文件
  • mockjs让前端开发独立于后端
  • Python3爬取英雄联盟英雄皮肤大图
  • Spark VS Hadoop:两大大数据分析系统深度解读
  • Spark学习笔记之相关记录
  • SQLServer之索引简介
  • Travix是如何部署应用程序到Kubernetes上的
  • 百度地图API标注+时间轴组件
  • 从0搭建SpringBoot的HelloWorld -- Java版本
  • 从0到1:PostCSS 插件开发最佳实践
  • 短视频宝贝=慢?阿里巴巴工程师这样秒开短视频
  • 关于List、List?、ListObject的区别
  • 前端设计模式
  • 区块链分支循环
  • 三分钟教你同步 Visual Studio Code 设置
  • 深入浅出webpack学习(1)--核心概念
  • 使用 Xcode 的 Target 区分开发和生产环境
  • 再次简单明了总结flex布局,一看就懂...
  • 正则与JS中的正则
  • 【运维趟坑回忆录】vpc迁移 - 吃螃蟹之路
  • 宾利慕尚创始人典藏版国内首秀,2025年前实现全系车型电动化 | 2019上海车展 ...
  • 数据可视化之下发图实践
  • ​​​​​​​Installing ROS on the Raspberry Pi
  • ​【已解决】npm install​卡主不动的情况
  • ​html.parser --- 简单的 HTML 和 XHTML 解析器​
  • ​iOS安全加固方法及实现
  • ​sqlite3 --- SQLite 数据库 DB-API 2.0 接口模块​
  • (14)Hive调优——合并小文件
  • (附源码)php新闻发布平台 毕业设计 141646
  • (附源码)spring boot公选课在线选课系统 毕业设计 142011
  • (附源码)spring boot智能服药提醒app 毕业设计 102151
  • (免费领源码)python#django#mysql公交线路查询系统85021- 计算机毕业设计项目选题推荐