首页 > 编程语言 >java线程池的一个小坑:shutdown之后线程并不会停止运行

java线程池的一个小坑:shutdown之后线程并不会停止运行

时间:2024-07-13 11:43:36浏览次数:13  
标签:java System future 线程 shutdown println executorService out

问题背景

最近我想要实现一个这样的功能:在线程运行超过一段时间之后就向主程序抛出一个异常,并停止这个线程。

其具体的应用场景是一个任务由多个子任务组成,每个子任务单独一个线程,如果某个子任务长时间未完成就认为这个子任务失败(可能是因为网络原因卡死了),就需要把这个线程结束掉,然后等待调度器重新运行这个子任务。

最初的解决方案及问题

最开始我们参考了网上最常见的解决办法,就是使用ExecutorService+Future,使用Future类的get方法来实现。但是后面实际部署上去之后发现,线程超时的异常被截获到了,但是线程依然在运行。

即使是使用了future.cancel和executorService.shutdown,正在运行的线程也不会停止,可以通过以下的示例代码来验证:

ExecutorService executorService= Executors.newSingleThreadExecutor();
Future<Object> future=executorService.submit(()->{
    while (true){
        try {
            Thread.sleep(1000);
        }catch (Exception e){
            e.printStackTrace();
        }

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

//            return null;
});

try {
    Object ret=future.get(3, TimeUnit.SECONDS);
    System.out.println("Got it");
}catch (Exception e){
    while(!future.cancel(false)){
        System.out.println("Cancel failed");
    }
    System.err.println("Error "+future.isCancelled());
    e.printStackTrace();
}finally {
    executorService.shutdown();
}

修改后的解决方案

个人推测应该是不存在可以强行停止线程的api,我们能做的只能是使用一个flag让线程自己停止运行,这个flag可以考虑使用executorService.isShutdown(),这个具体怎么做就得具体问题具体分析了,以下是修改后的示例代码:

ExecutorService executorService= Executors.newSingleThreadExecutor();
Future<Object> future=executorService.submit(()->{
    while (!executorService.isShutdown()){
        try {
            Thread.sleep(1000);
        }catch (Exception e){
            e.printStackTrace();
        }

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

    return null;
});

try {
    Object ret=future.get(3, TimeUnit.SECONDS);
    System.out.println("Got it");
}catch (Exception e){
    while(!future.cancel(false)){
        System.out.println("Cancel failed");
    }
    System.err.println("Error "+future.isCancelled());
    e.printStackTrace();
}finally {
    executorService.shutdown();
}

标签:java,System,future,线程,shutdown,println,executorService,out
From: https://www.cnblogs.com/qzero233/p/18299874

相关文章

  • JAVA设计模式>>结构型>>适配器模式
    本文介绍23种设计模式中结构型模式的适配器模式目录1. 适配器模式1.1 基本介绍1.2 工作原理 1.3  适配器模式的注意事项和细节1.4  类适配器模式1.4.1 类适配器模式介绍1.4.2 应用实例 1.4.3注意事项和细节1.5 对象适配器模式1.5.1 基本介绍1......
  • 【JavaScript脚本宇宙】创意无限:探索六款热门JavaScript图形库的魅力
    探索JavaScript图形库:深入了解网络操作和数据可视化工具前言在当今数字化时代,数据可视化和网络分析变得愈发重要。JavaScript图形库的出现为开发人员提供了丰富的工具和资源,帮助他们更轻松地创建复杂的网络图形和数据可视化效果。本文将介绍几个流行的JavaScript图形库,包......
  • 进程和线程之间的区别
    进程与线程的区别总结线程具有许多传统进程所具有的特征,故又称为轻型进程(Light—WeightProcess)或进程元;而把传统的进程称为重型进程(Heavy—WeightProcess),它相当于只有一个线程的任务。在引入了线程的操作系统中,通常一个进程都有若干个线程,至少包含一个线程。根本区别:进程......
  • 基于java+springboot+vue实现的作业管理系统(文末源码+Lw)110
    基于SpringBoot+Vue的实现的作业管理系统(源码+数据库+万字Lun文+流程图+ER图+结构图+演示视频+软件包)功能描述:作业管理系统有管理员,教师,学生三个角色。教师和学生都可以进行注册然后再登录。学生可以修改自己的密码,查看和下载作业信息,并且可以提交自己写好的作业,并且可以......
  • 基于java+springboot+vue实现的新闻稿件管理系统(文末源码+Lw)109
     基于SpringBoot+Vue的实现的新闻稿件管理系统(源码+数据库+万字Lun文+流程图+ER图+结构图+演示视频+软件包)系统功能:新闻稿件管理系统管理员功能有个人中心,用户管理,记者管理,审批员管理,新闻分类管理,新闻信息管理,系统管理等。记者发布新闻信息,审批员进行审核,用户进行查看。因......
  • 基于java+springboot+vue实现的在线试题库系统(文末源码+Lw)108
     基于SpringBoot+Vue的实现的在线试题库系统(源码+数据库+万字Lun文+流程图+ER图+结构图+演示视频+软件包) 系统功能:精品在线试题库系统有管理员,教师,学生三个角色。管理员功能有个人中心,专业管理,学生管理,教师管理,试卷管理,试题管理,考试管理。教师可以管理试题和试卷,查看学生......
  • JavaScript(9) ----this指向问题,bind,call,apply等方法
    目录this指向问题全局函数调用:对象方法调用:构造函数调用:事件处理:箭头函数:setTimeout和setInterval7.使用call、apply或bindcall方法apply方法bind方法总结this指向问题全局函数调用:在全局作用域中调用函数时,this指向全局对象(浏览器中是window对象)。fun......
  • Java简单学生信息管理系统
    importjava.io.;importjava.nio.file.;importjava.util.;importjava.util.stream.;classStudent{  privateStringid;  privateStringname;  privateintage;  privateStringaddress;publicStudent(Stringid,Stringname,intag......
  • 基于微信小程序的海鲜预订系统(后端JavaSSM+MySQL)
    目录摘要IAbstractII目录III第1章绪论11.1研究背景及意义11.1.1选题背景11.1.2选题意义11.2国内外研究现状及发展趋势21.2.1国外研究现状21.2.2国内研究现状21.2.3发展趋势31.3研究的主要内容3第2章系统技术52.1Java语言52.1.1......
  • Java基础之——final关键字的使用
    #Java基础复习##参考文章:Java:final关键字的作用(方法、变量、类)_java语言中在类定义时使用final关键字修饰是指这个类-CSDN博客#一、理解含义final是Java中一个保留的关键字,可以用于修饰变量、方法和类。任何实体(变量,方法或类)一旦被声明final后,只能分配(赋值)一次。也就是......