热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

并发编程深入解析:自定义并发类实现周期性任务调度

目录ScheduledThreadPoolExecutor一、主程序二、自定义周期线程池三、自定义周期任务类四、一个被执行的普通任务五、执行结果ScheduledThr

目录

ScheduledThreadPoolExecutor

一、主程序

二、自定义周期线程池

三、自定义周期任务类

四、一个被执行的普通任务

五、执行结果




ScheduledThreadPoolExecutor

周期调度性线程池(Scheduled thread pool)是一个Executor框架的基本线程池的拓展。


  • 延迟任务(Delayed task):在一段时间后执行一次。(可执行Callable和Runnable对象)
  • 周期任务(Periodic task):在一段时间后,永久地周期性地执行。(只能执行Runnable对象)

一、主程序

package xyz.jangle.thread.test.n8_6.schedule;import java.util.Date;
import java.util.concurrent.TimeUnit;/*** 8.6、自定义在周期调度线程池中运行的任务类* @author jangle* @email jangle@jangle.xyz* @time 2020年9月25日 上午9:20:05* */
public class M {public static void main(String[] args) throws Exception {// 使用自定义周期线程池MyScheduledThreadPoolExecutor executor = new MyScheduledThreadPoolExecutor(4);Task task = new Task();System.out.println("Main: " + new Date());executor.schedule(task, 1, TimeUnit.SECONDS);TimeUnit.SECONDS.sleep(6);task = new Task();System.out.println("Main:" + new Date());executor.scheduleAtFixedRate(task, 1, 3, TimeUnit.SECONDS);TimeUnit.SECONDS.sleep(10);executor.shutdown();executor.awaitTermination(1, TimeUnit.DAYS);System.out.println("Main:End of the program.");}}

二、自定义周期线程池

package xyz.jangle.thread.test.n8_6.schedule;import java.util.concurrent.RunnableScheduledFuture;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;/*** 自定义(继承重写)周期调度线程池* @author jangle* @email jangle@jangle.xyz* @time 2020年9月25日 下午3:15:44* */
public class MyScheduledThreadPoolExecutor extends ScheduledThreadPoolExecutor {public MyScheduledThreadPoolExecutor(int corePoolSize) {super(corePoolSize);}@Overrideprotected RunnableScheduledFuture decorateTask(Runnable runnable, RunnableScheduledFuture task) {// 该方法会被 schedule、scheduleAtFixedRate、scheduleWithFixedDelay 方法内部调用// 这个方法的任务是对原任务进行包装。// 包装后的任务必须是实现RunnableScheduledFuture接口的类(因为线程池需要判断是否是周期任务)return new MyScheduledTask(runnable, null, task, this);}@Overridepublic ScheduledFuture scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit) {// scheduleAtFixedRate 方法会调用decorateTask方法,所以会返回MyScheduledTask类型的对象ScheduledFuture task = super.scheduleAtFixedRate(command, initialDelay, period, unit);MyScheduledTask myTask = (MyScheduledTask) task;myTask.setPeriod(TimeUnit.MILLISECONDS.convert(period, unit));return myTask;}}

三、自定义周期任务类

在周期调度执行器中执行的任务必须实现RunnableScheduledFuture接口并拓展FutureTask类。

package xyz.jangle.thread.test.n8_6.schedule;import java.util.Date;
import java.util.concurrent.Delayed;
import java.util.concurrent.FutureTask;
import java.util.concurrent.RunnableScheduledFuture;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;/*** 自定义在周期调度线程池中运行的任务类* @author jangle* @email jangle@jangle.xyz* @time 2020年9月25日 上午9:22:49* */
public class MyScheduledTask extends FutureTask implements RunnableScheduledFuture {// 原任务private RunnableScheduledFuture task;// 线程池private ScheduledThreadPoolExecutor executor;// 运行周期private long period;// 用于周期任务(开始执行的时间)private long startDate;public MyScheduledTask(Runnable runnable, V result, RunnableScheduledFuture task,ScheduledThreadPoolExecutor executor) {super(runnable, result);this.task = task;this.executor = executor;}@Overridepublic long getDelay(TimeUnit unit) {if (!isPeriodic()) {return task.getDelay(unit);} else {if (startDate == 0) {return task.getDelay(unit);} else {var now = new Date();long delay = startDate - now.getTime();long res = unit.convert(delay, TimeUnit.MILLISECONDS);
// System.out.println("******delay:" + delay + ",res" + res);return res;}}}@Overridepublic int compareTo(Delayed o) {return task.compareTo(o);}@Overridepublic boolean isPeriodic() {return task.isPeriodic();}@Overridepublic void run() {if (isPeriodic() && (!executor.isShutdown())) {var now = new Date();startDate = now.getTime() + period;executor.getQueue().add(this);}System.out.println("MyScheduledTask-Pre:" + new Date());System.out.println("MyScheduledTask: 是否是周期性任务:" + isPeriodic());super.runAndReset();System.out.println("MyScheduledTask-Post:" + new Date());System.out.println("*************************");}public void setPeriod(long period) {this.period = period;}}

四、一个被执行的普通任务

package xyz.jangle.thread.test.n8_6.schedule;import java.util.concurrent.TimeUnit;/*** 普通的任务* @author jangle* @email jangle@jangle.xyz* @time 2020年9月25日 下午4:02:28* */
public class Task implements Runnable {@Overridepublic void run() {System.out.println("Task: Begin.");try {TimeUnit.SECONDS.sleep(2);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("Task: End.");}}

五、执行结果

Main: Sat Oct 03 09:23:16 CST 2020
MyScheduledTask-Pre:Sat Oct 03 09:23:17 CST 2020
MyScheduledTask: 是否是周期性任务:false
Task: Begin.
Task: End.
MyScheduledTask-Post:Sat Oct 03 09:23:19 CST 2020
*************************
Main:Sat Oct 03 09:23:22 CST 2020
MyScheduledTask-Pre:Sat Oct 03 09:23:23 CST 2020
MyScheduledTask: 是否是周期性任务:true
Task: Begin.
Task: End.
MyScheduledTask-Post:Sat Oct 03 09:23:25 CST 2020
*************************
MyScheduledTask-Pre:Sat Oct 03 09:23:26 CST 2020
MyScheduledTask: 是否是周期性任务:true
Task: Begin.
Task: End.
MyScheduledTask-Post:Sat Oct 03 09:23:28 CST 2020
*************************
MyScheduledTask-Pre:Sat Oct 03 09:23:29 CST 2020
MyScheduledTask: 是否是周期性任务:true
Task: Begin.
Task: End.
MyScheduledTask-Post:Sat Oct 03 09:23:31 CST 2020
*************************
Main:End of the program.

 


推荐阅读
  • spring boot使用jetty无法启动 ... [详细]
  • 问题场景用Java进行web开发过程当中,当遇到很多很多个字段的实体时,最苦恼的莫过于编辑字段的查看和修改界面,发现2个页面存在很多重复信息,能不能写一遍?有没有轮子用都不如自己造。解决方式笔者根据自 ... [详细]
  • 本文详细介绍了 `org.apache.tinkerpop.gremlin.structure.VertexProperty` 类中的 `key()` 方法,并提供了多个实际应用的代码示例。通过这些示例,读者可以更好地理解该方法在图数据库操作中的具体用途。 ... [详细]
  • 长期从事ABAP开发工作的专业人士,在面对行业新趋势时,往往需要重新审视自己的发展方向。本文探讨了几位资深专家对ABAP未来走向的看法,以及开发者应如何调整技能以适应新的技术环境。 ... [详细]
  • Beetl是一款先进的Java模板引擎,以其丰富的功能、直观的语法、卓越的性能和易于维护的特点著称。它不仅适用于高响应需求的大型网站,也适合功能复杂的CMS管理系统,提供了一种全新的模板开发体验。 ... [详细]
  • 问题描述现在,不管开发一个多大的系统(至少我现在的部门是这样的),都会带一个日志功能;在实际开发过程中 ... [详细]
  • 二维码的实现与应用
    本文介绍了二维码的基本概念、分类及其优缺点,并详细描述了如何使用Java编程语言结合第三方库(如ZXing和qrcode.jar)来实现二维码的生成与解析。 ... [详细]
  • Java 中的十进制样式 getZeroDigit()方法,示例 ... [详细]
  • JUnit下的测试和suite
    nsitionalENhttp:www.w3.orgTRxhtml1DTDxhtml1-transitional.dtd ... [详细]
  • 一、Advice执行顺序二、Advice在同一个Aspect中三、Advice在不同的Aspect中一、Advice执行顺序如果多个Advice和同一个JointPoint连接& ... [详细]
  • 本文详细介绍了JQuery Mobile框架中特有的事件和方法,帮助开发者更好地理解和应用这些特性,提升移动Web开发的效率。 ... [详细]
  • Irish budget airline Ryanair announced plans to significantly increase its route network from Frankfurt Airport, marking a direct challenge to Lufthansa, Germany's leading carrier. ... [详细]
  • 本文将详细介绍如何使用Java编程语言生成指定数量的不重复随机数,包括具体的实现方法和代码示例。适合初学者和有一定基础的开发者参考。 ... [详细]
  • 本文介绍了如何通过C#语言调用动态链接库(DLL)中的函数来实现IC卡的基本操作,包括初始化设备、设置密码模式、获取设备状态等,并详细展示了将TextBox中的数据写入IC卡的具体实现方法。 ... [详细]
  • Java中如何判断一个对象是否为Long类型
    本文介绍了一种在Java中判断对象是否属于Long类型的方法,通过定义一个特定的方法来实现这一功能,该方法能够准确地识别并返回结果。 ... [详细]
author-avatar
shadow
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有