Java ExcutorService优雅关闭方式解析

关闭时可使用如下代码

public static void waitUntilTerminate(final ExecutorService executorService, final int timeout) {
    try {
      executorService.shutdown();
      if (!executorService.awaitTermination(timeout, TimeUnit.SECONDS)) { //超时后直接关闭
        executorService.shutdownNow();
      }
    } catch (InterruptedException e) { //awaitTermination 出现中断异常也将触发关闭
      executorService.shutdownNow();
    }
  }

但是实际使用中,可能会出现即使使用了shutdownNow方法,还是无法终止线程的问题,那是因为你的线程无法被中断

shutdownNow方法简单理解就是给在运行的线程发一个中断信号,如果你的线程忽略这个信号,那就无法停下来

举个例子来说明这个问题

public class ShutDownUtilsTest {

  private ExecutorService executorService;

  @Before
  public void init() {
    executorService = Executors.newFixedThreadPool(1);
  }

  @Test
  public void shutDownOKTest() {
    ShutDownUtils.waitUntilTerminate(executorService, 1);

    CommonUtils.sleep(1); //等待线程处理中断
    Assert.assertTrue(executorService.isTerminated());
  }

  @Test
  public void shutDownNowFailTest() {
    executorService.execute(this::canNotStopThread);
    ShutDownUtils.waitUntilTerminate(executorService, 0);

    CommonUtils.sleep(1); //等待线程处理中断
    Assert.assertFalse(executorService.isTerminated());
  }

  @Test
  public void shutDownNowOKTest() {
    executorService.execute(this::stopThread);
    ShutDownUtils.waitUntilTerminate(executorService, 0);

    CommonUtils.sleep(1); //等待线程处理中断
    Assert.assertTrue(executorService.isTerminated());
  }

  private void canNotStopThread() {
    for (long i = 0; i < Long.MAX_VALUE; i++) {
    }
  }

  private void stopThread() {
    for (long i = 0; i < Long.MAX_VALUE && !Thread.currentThread().isInterrupted(); i++) {
    }
  }
}

从上面的测试用例可以看到canNotStopThread无法被shutDownNow终止

然而stopThread可以被正常终止,因为通过Thread.currentThread().isInterrupted()在判断线程是否收到了中断信号

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Java调用CXF WebService接口的两种方式实例

    通过http://localhost:7002/card/services/HelloWorld?wsdl访问到xml如下,说明接口写对了. 1.静态调用 // 创建WebService客户端代理工厂 JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean(); // 判断是否抛出异常 factory.getOutInterceptors().add(new LoggingInInterceptor()); // 注册webservic

  • Java调用WebService接口的方法

    本文实例讲述了Java调用WebService接口的方法.分享给大家供大家参考.具体如下: 这里讲述有参方法Add,代码如下: 复制代码 代码如下: public static void addTest() {         try ...{             Integer i = 1;             Integer j = 2;                         //WebService URL             String service_url =

  • 在spring boot中使用java线程池ExecutorService的讲解

    1. 认识java线程池 1.1 在什么情况下使用线程池? 1.单个任务处理的时间比较短 2.需处理的任务的数量大 1.2 使用线程池的好处: 1.减少在创建和销毁线程上所花的时间以及系统资源的开销 2.如不使用线程池,有可能造成系统创建大量线程而导致消耗完系统内存 1.3 线程池包括以下四个基本组成部分: 1.线程池管理器(ThreadPool):用于创建并管理线程池,包括 创建线程池,销毁线程池,添加新任务: 2.工作线程(PoolWorker):线程池中线程,在没有任务时处于等待状态,可以

  • Java ExecutorService四种线程池使用详解

    1.引言 合理利用线程池能够带来三个好处.第一:降低资源消耗.通过重复利用已创建的线程降低线程创建和销毁造成的消耗.第二:提高响应速度.当任务到达时,任务可以不需要的等到线程创建就能立即执行.第三:提高线程的可管理性.线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,调优和监控.但是要做到合理的利用线程池,必须对其原理了如指掌. 2.线程池使用 Executors提供的四种线程 1.newCachedThreadPool创建一个可缓存线程池

  • Java编程Webservice指定超时时间代码详解

    WebService是一种跨编程语言和跨操作系统平台的远程调用技术 所谓远程调用,就是一台计算机a上的一个程序可以调用到另外一台计算机b上的一个对象的方法,譬如,银联提供给商场的pos刷卡系统(采用交互提问的方式来加深大家对此技术的理解). 远程调用技术有什么用呢?商场的POS机转账调用的转账方法的代码是在银行服务器上,还是在商场的pos机上呢?什么情况下可能用到远程调用技术呢?例如,amazon,天气预报系统,淘宝网,校内网,百度等把自己的系统服务以webservice服务的形式暴露出来,让第

  • Java解析调用webservice服务的返回XML串详解

    本文由Markdown语法编辑器编辑完成. 1. 需求分析: 已知当在调用某一webservice的服务时,如果调用成功,会接受到该服务的返回XML串.后端在获取了该XML原始串时,需要进行解析,将其解析为JSON格式,以便于发送到前台,供前台页面显示和交互. 2. 解决方案: 该XML的原始形式为: <?xml version="1.0" encoding="UTF-8" ?> <SOAP-ENV:Envelope xmlns:SOAP-ENV=

  • java WSDL接口webService实现方式

    一.使用JDK生成WSDL的对象类 1.cmd进入JDK的bin文件中 执行命令 wsimport -keep -p com.demo.client http://localhost:8080/Demo/services/MyService?wsdl 比较常用的[options]有: 1). -d <directory> 在指定的目录生成class文件 2). -clientjar <jarfile> 在当前目录生成jar文件,结合-d <directory>可以在指定

  • Java ExcutorService优雅关闭方式解析

    关闭时可使用如下代码 public static void waitUntilTerminate(final ExecutorService executorService, final int timeout) { try { executorService.shutdown(); if (!executorService.awaitTermination(timeout, TimeUnit.SECONDS)) { //超时后直接关闭 executorService.shutdownNow()

  • Java创建线程的方式解析

    目录 继承Thread,这里使用匿名内部类 实现Runnable接口,配合Thread类,同样用匿名内部类 FutureTask配合Thread 继承Thread,这里使用匿名内部类 @Slf4j(topic = "c.Test1") public class Test1 { public static void main(String[] args) { //创建线程对象 Thread t = new Thread(){ @Override public void run() { /

  • Java如何优雅地关闭资源try-with-resource及其异常抑制

    一.背景 我们知道,在Java编程过程中,如果打开了外部资源(文件.数据库连接.网络连接等),我们必须在这些外部资源使用完毕后,手动关闭它们.因为外部资源不由JVM管理,无法享用JVM的垃圾回收机制,如果我们不在编程时确保在正确的时机关闭外部资源,就会导致外部资源泄露,紧接着就会出现文件被异常占用,数据库连接过多导致连接池溢出等诸多很严重的问题.  二.传统的资源关闭方式 为了确保外部资源一定要被关闭,通常关闭代码被写入finally代码块中,当然我们还必须注意到关闭资源时可能抛出的异常,于是变

  • Java sort集合排序的两种方式解析

    这篇文章主要介绍了Java sort集合排序的两种方式解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 Comparable和Comparator public static <T> void sort(List<T> list); 将集合中的数据按照默认规则进行排序 (我们在自己的类里面实现Comparabl接口方法compareTo) public static <T> void sort(List<T&g

  • Java synchronized关键字使用方式及特性解析

    这篇文章主要介绍了Java synchronized关键字使用方式及特性解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 synchronized 关键字是实现锁的一种方式,是在jvm层面实现的非公平锁,以下是使用synchronized的四种方式 synchronized 特性: 1.非公平锁 2.可重入性 1.作用在方法上,保证了访问同一个对象的同一个方法的线程同步 public synchronized void testFun(Str

  • Java map 优雅的元素遍历方式说明

    Java 8 , Lambda + foreach 语法糖, 写起来非常的 clean public static void main(String[] args) { // map init Map<String, String> map = new HashMap<>(); map.put("k", "v"); /*=====处理函数只有单条语句=====*/ map.forEach((k, v) -> System.out.pri

  • java 优雅关闭线程池的方案

    我们经常在项目中使用的线程池,但是是否关心过线程池的关闭呢,可能很多时候直接再项目中直接创建线程池让它一直运行当任务执行结束不在需要了也不去关闭,这其实是存在非常大的风险的,大量的线程常驻在后台对系统资源的占用是巨大的 ,甚至引发异常.所以在我们平时使用线程池时需要注意优雅的关闭,这样可以保证资源的管控. 在 Java 中和关闭线程池相关的方法主要有如下: void shutdown() List<Runnable> shutDownNow boolean awaitTermination b

  • Java多线程导致CPU占用100%解决及线程池正确关闭方式

    简介 情景:1000万表数据导入内存数据库,按分页大小10000查询,多线程,15条线程跑. 使用了ExecutorService executor = Executors.newFixedThreadPool(15) 本地跑了一段时间后,发现电脑CPU逐渐升高,最后CPU占用100%卡死,内存使用也高达80%. 排查问题 Debug 发现虽然创建了定长15的线程池,但是因为数据量大,在For中循环分页查询的List会持续加入LinkedBlockingQueue() 队列中每一个等待的任务,又

  • Java中后台线程实例解析

    本文研究的主要是Java中后台线程的相关问题,具体介绍如下. 以前从来没有听说过,java中有后台线程这种东西.一般来说,JVM(JAVA虚拟机)中一般会包括俩种线程,分别是用户线程和后台线程.所谓后台线程(daemon)线程指的是:在程序运行的时候在后台提供的一种通用的服务的线程,并且这种线程并不属于程序中不可或缺的部分.因此,当所有的非后台线程结束的时候,也就是用户线程都结束的时候,程序也就终止了.同时,会杀死进程中的所有的后台线程.反过来说,只要有任何非后台线程还在运行,程序就不会结束.不

  • Java Web开发入门书籍实例解析(总结一)

    从事Java Web开发这一段时间来,对Java 面向对象的思想和MVC开发模式可以说已经熟悉了.我当前参与的项目使用的框架是Spring.SpringMVC.Hibernate.下面我们小编给大家整理一篇教程帮助大家学习javaweb相关知识,感兴趣的朋友可以参考下. 一.基本概念 1.1.WEB开发的相关知识 WEB,在英语中web即表示网页的意思,它用于表示Internet主机上供外界访问的资源. Internet上供外界访问的Web资源分为: 1.静态web资源(如html 页面):指w

随机推荐