博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
JAVA线程池ScheduledExecutorService周期性地执行任务 与单个Thread周期性执行任务的异常处理...
阅读量:6916 次
发布时间:2019-06-27

本文共 4130 字,大约阅读时间需要 13 分钟。

本文记录:

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大于5        ScheduledFuture
result = executorService.scheduleAtFixedRate(task1, 0, 1, TimeUnit.SECONDS);

此时,如果注释掉 //executorService.shutdown(); 则线程池不会中止,因为这是一个线程池,但是由于线程执行过程中抛出了异常,任务也不会周期性地执行了。参考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方法设置异常处理。关于异常处理,可参考:

第15-18行,线程每隔4s提交一次任务,从而实现任务的周期性执行。 

 

异常处理类ExceptionHandler类实现了UncaughtExceptionHandler接口,然后在uncaughtException方法里面定义具体的异常处理过程即可。

import java.lang.Thread.UncaughtExceptionHandler;public class ExceptionHandler implements UncaughtExceptionHandler{    @Override    public void uncaughtException(Thread t, Throwable e) {        System.out.println("illegal exception: 计算的阶乘大于5了," + e.getMessage());    }}

 

与线程池方式相比 ,这种方式是每个周期,都要new一个线程。而线程池则是每个周期new一个任务,把任务提交给线程池即可。

原文:http://www.cnblogs.com/hapjin/p/7616068.html

你可能感兴趣的文章
centos rocksdb 性能测试笔记(二)
查看>>
iOS开发之多线程浅析
查看>>
jquery 读书笔记
查看>>
修改监控录像时间的方法以及基础常识,必看! ...
查看>>
Troubleshooting High CPU Usage on Alibaba Cloud SQL Server
查看>>
手把手教你监督学习(附python实战代码)
查看>>
DataSet筛选数据然后添加到新的DataSet中引发的一系列血案
查看>>
设置select下拉菜单的默认选中项
查看>>
exe4j的使用
查看>>
TNS-12535 TNS-00505的处理方法
查看>>
R语言:数据输出至文件
查看>>
Linux下搭建 NFS
查看>>
VR AR创新创业大赛顺利收官,行业大咖看好移动VR发展
查看>>
Vive戴起来不够舒服?SynergyWiz为其设计了翻盖
查看>>
新年快乐,介绍个简单的Excel理财工作的制作方法
查看>>
[翻译-ASP.NET MVC]Contact Manager开发之旅之迭代1 - 创建Contact Manager应用
查看>>
Linux C 下使用openssl 进行SHA1加密
查看>>
4星|《我的第一本创业融资指南》:投资人写的创业者融资指南
查看>>
再现一分钱中标,中国电信拿下海南政务云项目
查看>>
文件服务器之二:FTP服务器(pureftp)
查看>>