使用ExecutorService来停止线程服务

之前的文章中我们提到了ExecutorService可以使用shutdown和shutdownNow来关闭。

这两种关闭的区别在于各自的安全性和响应性。shutdownNow强行关闭速度更快,但是风险也更大,因为任务可能正在执行的过程中被结束了。而shutdown正常关闭虽然速度比较慢,但是却更安全,因为它一直等到队列中的所有任务都执行完毕之后才关闭。

使用shutdown

我们先看一个使用shutdown的例子:

public void useShutdown() throws InterruptedException {

ExecutorService executor = Executors.newFixedThreadPool(10);

Runnable runnableTask = () -> {

try {

TimeUnit.MILLISECONDS.sleep(300);

} catch (InterruptedException e) {

e.printStackTrace();

}

};

executor.submit(runnableTask);

executor.shutdown();

executor.awaitTermination(800, TimeUnit.MILLISECONDS);

}

awaitTermination将会阻塞直到所有正在执行的任务完成,或者达到指定的timeout时间。

使用shutdownNow

当通过shutdownNow来强行关闭ExecutorService是, 它会尝试取消正在执行的任务,并返回所有已经提交但是还没有开始的任务。从而可以将这些任务保存起来,以便以后进行处理。

但是这样我们只知道了还没有开始执行的任务,对于那些已经开始执行但是没有执行完毕却被取消的任务我们无法获取。

我们看下如何获得开始执行但是还没有执行完毕的任务:

public class TrackingExecutor extends AbstractExecutorService {

private final ExecutorService executorService;

private final Set taskCancelledAtShutdown= Collections.synchronizedSet(new HashSet());

public TrackingExecutor(ExecutorService executorService){

this.executorService=executorService;

}

@Override

public void shutdown() {

executorService.shutdown();

}

@Override

public List shutdownNow() {

return executorService.shutdownNow();

}

@Override

public boolean isShutdown() {

return executorService.isShutdown();

}

@Override

public boolean isTerminated() {

return executorService.isTerminated();

}

@Override

public boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException {

return executorService.awaitTermination(timeout,unit);

}

@Override

public void execute(Runnable command) {

executorService.execute(() -> {

try {

command.run();

}finally {

if(isShutdown() && Thread.currentThread().isInterrupted()){

taskCancelledAtShutdown.add(command);

}

}

});

}

public List getCancelledTask(){

if(! executorService.isTerminated()){

throw new IllegalStateException("executorService is not terminated");

}

return new ArrayList<>(taskCancelledAtShutdown);

}

}

上面的例子中我们构建了一个新的ExecutorService,他传入一个ExecutorService,并对其进行封装。

我们重写了execute方法,在执行完毕判断该任务是否被中断,如果被中断则将其添加到CancelledTask列表中。

并提供一个getCancelledTask方法来返回未执行完毕的任务。

我们看下怎么使用:

public void useShutdownNow() throws InterruptedException {

TrackingExecutor trackingExecutor=new TrackingExecutor(Executors.newCachedThreadPool());

Runnable runnableTask = () -> {

try {

TimeUnit.MILLISECONDS.sleep(300);

} catch (InterruptedException e) {

e.printStackTrace();

}

};

trackingExecutor.submit(runnableTask);

List notrunList=trackingExecutor.shutdownNow();

if(trackingExecutor.awaitTermination(800, TimeUnit.SECONDS)){

List runButCancelledList= trackingExecutor.getCancelledTask();

}

}

trackingExecutor.shutdownNow()返回的是未执行的任务。而trackingExecutor.getCancelledTask()返回的是被取消的任务。

上面的任务其实还有一个缺点,因为我们在存储被取消的任务列表的额时候taskCancelledAtShutdown.add(command),因为之前的判断不是原子操作,则可能会产生误报。

到此这篇关于Java使用ExecutorService来停止线程服务的文章就介绍到这了,更多相关Java ExecutorService停止线程内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

java executorser 停止_Java使用ExecutorService来停止线程服务相关推荐

  1. tomcat 停止 java 线程不停止_Java Tomcat,底层Netty线程不停止

    我正在尝试使用log4j appender将日志发送到GrayLog2(log4j2-gelf).所以我加我的依赖到我的pom.xml配置log4j2.xml来配置我的appender.用maven构 ...

  2. java守护锁_Java 对象锁-synchronized()与线程的状态与生命周期与守护进程

    synchronized(someObject){ //对象锁 } 一.对象锁 someObject 的使用说明: 1.对象锁的返还. 当synchronize()语句执行完成. 当synchroni ...

  3. java 静态类 安全_Java静态static工具类线程安全问题研究

    针对静态方法有以下一些前提: 静态方法和实例方法的区别是静态方法只能引用静态变量,静态方法通过类名来调用,实例方法通过对象实例来调用 每个线程都有自己的线程栈,栈与线程同时创建,每一个虚拟机线程都有自 ...

  4. java 微网站_java架构之路-(微服务专题)初步认识微服务与nacos初步搭建

    历史演变: 以前我们都是一个war包,包含了很多很多的代码,反正我开始工作的时候做的就是这样的项目,一个金融系统,代码具体多少行记不清楚了,内部功能超多,但是实际能用到的不多,代码冗余超大,每次部署大 ...

  5. java app支付_Java 微信支付之APP支付服务端 (一)

    Java 微信支付之APP支付服务端 (一) 如图所示,这是服务端要集成的所有微信接口.至于在开放平台申请就不做赘述了.主要流程,1.下单,2.异步通知,3.查询. 一.微信统一下单请求交易 /** ...

  6. java arraycopy 并发_java中System.arraycopy是线程安全的吗?

    System.arraycopy 是一个 native 方法: public static native void arraycopy(Object src, int srcPos, Object d ...

  7. java websocket 实现_JAVA (Tomcat服务器)使用WebSocket实现服务端与HTML前端通信

    在一个项目中要使用WebSocket技术来实现服务器与浏览器实时通信交互,在网上也找了许多资料.为了防止以后忘记具体的使用过程,下面我把自己的使用过程和方法记录下来方便自己以后使用. 项目背景: 基于 ...

  8. java drawstring 截断_java中怎要用线程不断重写drawstring 方法

    我用线程序写了一个时间程序,想用父类的drawstring方法将其输入到面板上,怎样调用?希望详细一点如drawstring(s,1,1),要求不断重写s来动态显示时间程序如下,不知道怎么一直重写s: ...

  9. 如何让java程序执行一段时间后停止

    如何让java程序执行一段时间后停止 1.概述 在本文中,我们将学习如何在一段时间后结束长时间运行的任务.我们将探讨这个问题的各种解决方案.此外,还将介绍各种方案缺点. 2.使用循环 假设我们在一个循 ...

最新文章

  1. 【Android】显示Emoji表情字符
  2. python基础一入门必备知识-python基础教程#菜鸟也能看懂的超简单入门必备知识...
  3. phpcms数据库操作
  4. 使用Q进行同步的Promises操作
  5. input标签用法解读
  6. vb使用字符串分隔字符串_为什么要使用字符串
  7. Linux程序设计01:开发工具和开发平台
  8. 【模板】最新空web.xml模板
  9. jbpm知识点——state
  10. 有关c#.net“无法加载 CSOpenGLC.dll:找不到指定的模块”的问题解决办法
  11. java 学习第三篇if判断
  12. 【VS2010学习笔记】【编程实例】 (含有类的动态链接库的封装和调用)
  13. dtft性质及证明_FFT , DTFT, DFT 的区别和联系?
  14. 增量学习(Incremental Learning)小综述
  15. [官方文档翻译:kind]HOME
  16. 《求职》第三部分 - 计算机网络篇 - 计算机网络总结
  17. android 隐藏电池,Android8.1隐藏状态栏电池图标
  18. 计算机操作系统——(第四章) 存储器管理/内存管理
  19. Janus源码分析(1)——源码结构
  20. 计算机状态oxc0000001,电脑蓝屏代码0x00000001解决方法

热门文章

  1. [Python]数据类型、常量、变量和运算符(未完待续)
  2. jquery实现动态五角星评分
  3. 详解设计模式之工厂模式(简单工厂+工厂方法+抽象工厂)
  4. 在PHP中如何使用消息列队
  5. sonar 代码质量管理平台
  6. 由oschina.neT了解到博客备份的代码
  7. 基于移动设备的Wifi开发组件
  8. 将外部知识整合到群体智能中,以获得更具体的知识
  9. 一个1990年代的小故事
  10. Nutch爬虫引擎使用分析