Java:自定义ScheduledExecutorService来实现定时提交任务
2021/7/4 14:23:06
本文主要是介绍Java:自定义ScheduledExecutorService来实现定时提交任务,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
1. 声明
当前内容主要为本人学习和复习定时任务
一般的定时任务:
- 使用Executors.newScheduledThreadPool方式创建
- 调用scheduleWithFixedDelay来定时执行
主要为实现定时周期性任务,但是每个周期性的任务执行的时间不确定,这个就导致一些问题例如:必须每天提交日志信息(不能延迟)
2.newScheduledThreadPool的demo
如下:一个1秒钟的定时任务
public static void main(String[] args) { ScheduledExecutorService newScheduledThreadPool = Executors.newScheduledThreadPool(3); DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); Runnable run = () -> { String name = Thread.currentThread().getName(); System.out.println(name + ":正在执行任务!" + format.format(new Date())); try { Thread.sleep(4000l); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(name + ":执行完毕!" + format.format(new Date())); }; try { /* newScheduledThreadPool.schedule(run, 1000L, TimeUnit.MILLISECONDS); */ newScheduledThreadPool.scheduleWithFixedDelay(run, 0L, 1000L, TimeUnit.MILLISECONDS); System.out.println("执行任务完毕了吗?"); } catch (Exception ex) { ex.printStackTrace(); } }
但是实际任务在runnable中模拟执行时间为4秒
执行结果为:
无论将初始化的poolSize设置为多少,那么永远只有一个在执行,并且执行间隔为上一个任务执行完毕后+1秒(这个有的时候并不符合我们的任务要求)
就像现实生活中,任务并不会等待后再执行,而是继续提交执行
3. 自定的实现方式定时提交任务
1.任务必须定时提交,不关心执行任务的完成时间(可以考虑使用定时器+线程池方式)
public class MySchaduleThread implements ScheduledExecutorService { private final int poolMaxSize; private final ScheduledExecutorService scheduledExecutorService; // 控制定时任务 private final ExecutorService executorService;// 控制执行任务,按照时间间隔将定时任务交给这个进行处理 // 缺少线程状态的记录,缺少已经正在执行的任务线程数量记录 // 缺少日志信息 public MySchaduleThread(int poolMaxSize) { this.scheduledExecutorService = Executors.newScheduledThreadPool(1); this.poolMaxSize = poolMaxSize; this.executorService = Executors.newFixedThreadPool(poolMaxSize); } public static void main(String[] args) { MySchaduleThread schaduleThread=new MySchaduleThread(5); DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); Runnable run = () -> { String name = Thread.currentThread().getName(); System.out.println(name + ":正在执行任务!" + format.format(new Date())); try { Thread.sleep(4000l); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(name + ":执行完毕!" + format.format(new Date())); }; schaduleThread.scheduleWithFixedDelay(run, 0, 1000L, TimeUnit.MILLISECONDS); } @Override public void shutdown() { executorService.shutdown(); scheduledExecutorService.shutdown(); } @Override public List<Runnable> shutdownNow() { scheduledExecutorService.shutdownNow(); List<Runnable> shutdownNow = executorService.shutdownNow(); return shutdownNow; } @Override public boolean isShutdown() { // TODO Auto-generated method stub return false; } @Override public boolean isTerminated() { // TODO Auto-generated method stub return false; } @Override public boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException { // TODO Auto-generated method stub return false; } @Override public <T> Future<T> submit(Callable<T> task) { // TODO Auto-generated method stub return null; } @Override public <T> Future<T> submit(Runnable task, T result) { // TODO Auto-generated method stub return null; } @Override public Future<?> submit(Runnable task) { // TODO Auto-generated method stub return executorService.submit(task); } @Override public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) throws InterruptedException { // TODO Auto-generated method stub return null; } @Override public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit) throws InterruptedException { // TODO Auto-generated method stub return null; } @Override public <T> T invokeAny(Collection<? extends Callable<T>> tasks) throws InterruptedException, ExecutionException { // TODO Auto-generated method stub return null; } @Override public <T> T invokeAny(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { // TODO Auto-generated method stub return null; } @Override public void execute(Runnable command) { // TODO Auto-generated method stub } @Override public ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit) { // TODO Auto-generated method stub return null; } @Override public <V> ScheduledFuture<V> schedule(Callable<V> callable, long delay, TimeUnit unit) { // TODO Auto-generated method stub return null; } @Override public ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit) { // TODO Auto-generated method stub return null; } @Override public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit) { return scheduledExecutorService.scheduleWithFixedDelay(() -> { submit(command); }, initialDelay, delay, unit); } }
执行结果:
测试是成功
4. 思考
1. 由于上面的是最简单的版本实现的,但是可能存在所有执行的线程都是繁忙,出现最后线程不处理的情况,需要处理其他的问题
2. 线程必须提交所有执行任务的状态,可以实现线程的任务的自由取消,执行超时等
3. 线程必须有最大执行数量控制,各种错误处理等
这篇关于Java:自定义ScheduledExecutorService来实现定时提交任务的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23Springboot应用的多环境打包入门
- 2024-11-23Springboot应用的生产发布入门教程
- 2024-11-23Python编程入门指南
- 2024-11-23Java创业入门:从零开始的编程之旅
- 2024-11-23Java创业入门:新手必读的Java编程与创业指南
- 2024-11-23Java对接阿里云智能语音服务入门详解
- 2024-11-23Java对接阿里云智能语音服务入门教程
- 2024-11-23JAVA对接阿里云智能语音服务入门教程
- 2024-11-23Java副业入门:初学者的简单教程
- 2024-11-23JAVA副业入门:初学者的实战指南