JAVA线程池ScheduledExecutorService周期性地执行任务 与单个Thread周期性执行任务的异常处理...
本文记录:
1,使用ScheduledExecutorService的 scheduleAtFixedRate 方法执行周期性任务的过程,讨论了在任务周期执行过程中出现了异常,会导致周期任务失败。
2,使用普通的Thread类来执行任务,在main线程中周期性创建线程,提交任务。然后,使用UncaughtExceptionHandler来处理异常。
一,正常任务执行
负责执行任务的线程类如下:(一个计算阶乘的任务,计算5以上的阶乘,就会抛出异常)
1 public class FactorialCalc implements Runnable { 2 3 private Integer number; 4 5 public FactorialCalc(Integer number) { 6 this.number = number; 7 } 8 9 public void run() { 10 11 int result = 1; 12 13 if (number == 0) { 14 System.out.println("0!=" + "1"); 15 } 16 17 if (number > 5) { 18 System.out.println("exception"); 19 throw new IllegalArgumentException(">5"); 20 } 21 22 for(int i = 1; i <= number; i++) { 23 result *= i; 24 25 } 26 System.out.println(number + "!=" + result); 27 } 28 }
测试的Main类如下:
1 public class MainPeriod { 2 3 public static void main(String[] args) { 4 5 ScheduledExecutorService executorService = Executors.newScheduledThreadPool(2); 6 7 FactorialCalc task1 = new FactorialCalc(6); 8 FactorialCalc task2 = new FactorialCalc(3); 9 10 ScheduledFuture<?> result = executorService.scheduleAtFixedRate(task1, 0, 1, TimeUnit.SECONDS); 11 // ScheduledFuture<?> result = executorService.scheduleAtFixedRate(task2, 0, 2, TimeUnit.SECONDS); 12 13 try { 14 TimeUnit.SECONDS.sleep(5); 15 executorService.shutdown(); 16 } catch (InterruptedException e) { 17 e.printStackTrace(); 18 } 19 } 20 }
ScheduledFuture<?> result = executorService.scheduleAtFixedRate(task1, 0, 1, TimeUnit.SECONDS);
提交一个Runnable任务,延迟为0,每1秒钟执行一次。
二,线程 执行过程中出现异常
当提交 task1 时,线程在执行过程中会抛出异常。
FactorialCalc task1 = new FactorialCalc(6);//计算6的阶乘,6大于5ScheduledFuture<?> result = executorService.scheduleAtFixedRate(task1, 0, 1, TimeUnit.SECONDS);
此时,如果注释掉 //executorService.shutdown(); 则线程池不会中止,因为这是一个线程池,所有的异常都由线程池catch住了。但是由于线程执行过程中抛出了异常,任务也不会周期性地执行了。参考JDK里面的scheduleAtFixedRate注释:
* If any execution of the task* encounters an exception, subsequent executions are suppressed.public ScheduledFuture<?> scheduleAtFixedRate(Runnable command,long initialDelay,long period,TimeUnit unit);
三,关闭线程池 ,执行 executorService.shutdown() 语句
若线程池线程 执行任务过程中抛出了异常,但是在 主线程中 执行了executorService.shutdown() 语句,则会正常关闭 线程池。
四,总结
使用ScheduledExecutorService的 scheduleAtFixedRate 方法执行周期性任务时,如果任务一直正常执行,则任务会按设定的执行周期一直在运行(前提是,主线程内不要调用executorService.shutdown() ,比如需要 执行 永久性的周期性任务,那就不能调用 executorService.shutdown() )。
如果任务在某次执行过程中抛出了异常,则周期性任务会被中断,后续也不会再生成任务了,如果主线程 也没有 调用 executorService.shutdown() ,那线程池就不会关闭了。
五,使用Thread类执行任务,在Main线程中通过while循环周期性提交任务,使用UncaughtExceptionHandler来处理异常
1 import java.util.Random; 2 import java.util.concurrent.TimeUnit; 3 4 public class Main { 5 6 public static void main(String[] args) { 7 8 Random rand = new Random(); 9 10 while(true){ 11 int number = rand.nextInt(10); 12 Thread t = new Thread(new FactorialCalc(number)); 13 t.setUncaughtExceptionHandler(new ExceptionHandler()); 14 t.start(); 15 try{ 16 System.out.println("sleep 4s for next task"); 17 TimeUnit.SECONDS.sleep(4); 18 }catch(InterruptedException e){ 19 20 } 21 } 22 } 23 }
在main方法中使用一个while(true)循环,周期性地创建线程 提交任务。
第12-13行,每创建一个线程,调用setUncaughtExceptionHandler方法设置异常处理。关于异常处理,可参考:JAVA线程未捕获异常处理
第15-18行,线程每隔4s提交一次任务,从而实现任务的周期性执行。
异常处理类ExceptionHandler类实现了UncaughtExceptionHandler接口,然后在uncaughtException方法里面定义具体的异常处理过程即可。
import java.lang.Thread.UncaughtExceptionHandler;public class ExceptionHandler implements UncaughtExceptionHandler{@Overridepublic void uncaughtException(Thread t, Throwable e) {System.out.println("illegal exception: 计算的阶乘大于5了," + e.getMessage());} }
与线程池方式相比 ,这种方式是每个周期,都要new一个线程。而线程池则是每个周期new一个任务,把任务提交给线程池即可。
原文:http://www.cnblogs.com/hapjin/p/7616068.html
转载于:https://www.cnblogs.com/hapjin/p/7616068.html
JAVA线程池ScheduledExecutorService周期性地执行任务 与单个Thread周期性执行任务的异常处理...相关推荐
- JAVA线程池ScheduledExecutorService周期性地执行任务 与单个Thread周期性执行任务的异常处理
JAVA线程池ScheduledExecutorService周期性地执行任务 与单个Thread周期性执行任务的异常处理 参考文章: (1)JAVA线程池ScheduledExecutorServi ...
- java线程池使用详解ThreadPoolExecutor使用示例
一 使用线程池的好处 二 Executor 框架 2.1 简介 2.2 Executor 框架结构(主要由三大部分组成) 1) 任务(Runnable /Callable) 2) 任务的执行(Exec ...
- java 线程池的使用_Java 使用线程池执行若干任务
在执行一系列带有IO操作(例如下载文件),且互不相关的异步任务时,采用多线程可以很极大的提高运行效率.线程池包含了一系列的线程,并且可以管理这些线程.例如:创建线程,销毁线程等.本文将介绍如何使用Ja ...
- scheduled线程池ScheduledExecutorService只执行一次_有个定时任务突然不执行了
scheduled线程池ScheduledExecutorService只执行一次_有个定时任务突然不执行了 原因 If any execution of the task encounters an ...
- java线程池延期执行一次_Java使用者的延期执行
java线程池延期执行一次 在前面的博客文章(" 延迟执行Java的供应商 "),我引用礁HORSTMANN的陈述书中' 的Java SE8为真的很急关于lambda表达式','所 ...
- Java 监控线程池所有任务是否执行完毕
Java 监控线程池所有任务是否执行完毕 场景引入 在最近的工作中遇到一个需要批量生产百万数据并写入数据库的需求,先通过单线程的方式去实现,但是感觉效率一般,然后通过多线程的方式去改进,但是遇到下面的 ...
- Java线程池参数、执行流程及线程数配置建议
1. 线程池参数详解 corePoolSize:线程池中常驻核心线程数: maximumPoolSize:线程池能够容纳同时执行的最大线程数: keepAliveTime:多余的空闲线程存活时间: u ...
- Java线程池了解一下
前言 马上就要过年了,还在岗位上坚守"swimming"的小伙伴们顶住.博主给大家带来一篇线程池的基本使用解解闷. 为什么需要使用线程池 1.减少线程创建与切换的开销 在没有使用线 ...
- 由浅入深理解Java线程池及线程池的如何使用
前言 多线程的异步执行方式,虽然能够最大限度发挥多核计算机的计算能力,但是如果不加控制,反而会对系统造成负担.线程本身也要占用内存空间,大量的线程会占用内存资源并且可能会导致Out of Memory ...
最新文章
- 标称变量(Categorical Features)或者分类变量(Categorical Features​​​​​​​)缺失值填补、详解及实战
- 夜宵虽好,可不要贪“杯”哦
- Autolisp:利用AuoCAD之Lisp编程案例之自动智能获取所选对象的面积并标注在指定位置
- iis7配置php-7,PHP--Windows 7 +IIS7配置
- Nmap经常使用的场景用法
- 光端机图像出现噪点或者数据有时不通的情况
- EDM数据库营销是什么?-EDM数据库营销的概念
- 用phpcms如何将静态页面制作成企业网站(上)
- http请求代理proxy-ajax
- 数字视频内容行业调研报告 - 市场现状分析与发展前景预测
- idea 格式化代码怎么才能不格式化代码注释?
- golang 隐藏启动其他程序,包含cmd窗口(黑窗口)程序,GUI程序隐藏
- windows自动化操作——程序员必备
- 基于Java的亚马逊“手机”评论爬虫的情感分类分析
- SpringBoot+MyBatis+MySql实现的医院管理系统
- 人工智能(Machine Learning)—— 机器学习
- 【每日一题】039 手机尾数
- 英语水平不强,如何写出高质量英文论文?五个英语写作辅助和润色软件!
- 遗传算法(GA)详解
- Python快速实现选择排序