热门标签 | 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.

 


推荐阅读
  • Python 异步编程:深入理解 asyncio 库(上)
    本文介绍了 Python 3.4 版本引入的标准库 asyncio,该库为异步 IO 提供了强大的支持。我们将探讨为什么需要 asyncio,以及它如何简化并发编程的复杂性,并详细介绍其核心概念和使用方法。 ... [详细]
  • 本文介绍如何使用Objective-C结合dispatch库进行并发编程,以提高素数计数任务的效率。通过对比纯C代码与引入并发机制后的代码,展示dispatch库的强大功能。 ... [详细]
  • 本文介绍了Java并发库中的阻塞队列(BlockingQueue)及其典型应用场景。通过具体实例,展示了如何利用LinkedBlockingQueue实现线程间高效、安全的数据传递,并结合线程池和原子类优化性能。 ... [详细]
  • 深入理解 SQL 视图、存储过程与事务
    本文详细介绍了SQL中的视图、存储过程和事务的概念及应用。视图为用户提供了一种灵活的数据查询方式,存储过程则封装了复杂的SQL逻辑,而事务确保了数据库操作的完整性和一致性。 ... [详细]
  • 本文详细介绍了 Dockerfile 的编写方法及其在网络配置中的应用,涵盖基础指令、镜像构建与发布流程,并深入探讨了 Docker 的默认网络、容器互联及自定义网络的实现。 ... [详细]
  • 本文详细介绍了Akka中的BackoffSupervisor机制,探讨其在处理持久化失败和Actor重启时的应用。通过具体示例,展示了如何配置和使用BackoffSupervisor以实现更细粒度的异常处理。 ... [详细]
  • 本文详细解析了Python中的os和sys模块,介绍了它们的功能、常用方法及其在实际编程中的应用。 ... [详细]
  • 掌握远程执行Linux脚本和命令的技巧
    本文将详细介绍如何利用Python的Paramiko库实现远程执行Linux脚本和命令,帮助读者快速掌握这一实用技能。通过具体的示例和详尽的解释,让初学者也能轻松上手。 ... [详细]
  • 本文将介绍如何编写一些有趣的VBScript脚本,这些脚本可以在朋友之间进行无害的恶作剧。通过简单的代码示例,帮助您了解VBScript的基本语法和功能。 ... [详细]
  • Explore how Matterverse is redefining the metaverse experience, creating immersive and meaningful virtual environments that foster genuine connections and economic opportunities. ... [详细]
  • 技术分享:从动态网站提取站点密钥的解决方案
    本文探讨了如何从动态网站中提取站点密钥,特别是针对验证码(reCAPTCHA)的处理方法。通过结合Selenium和requests库,提供了详细的代码示例和优化建议。 ... [详细]
  • 本文详细介绍了如何在Linux系统上安装和配置Smokeping,以实现对网络链路质量的实时监控。通过详细的步骤和必要的依赖包安装,确保用户能够顺利完成部署并优化其网络性能监控。 ... [详细]
  • 1.如何在运行状态查看源代码?查看函数的源代码,我们通常会使用IDE来完成。比如在PyCharm中,你可以Ctrl+鼠标点击进入函数的源代码。那如果没有IDE呢?当我们想使用一个函 ... [详细]
  • 在前两篇文章中,我们探讨了 ControllerDescriptor 和 ActionDescriptor 这两个描述对象,分别对应控制器和操作方法。本文将基于 MVC3 源码进一步分析 ParameterDescriptor,即用于描述 Action 方法参数的对象,并详细介绍其工作原理。 ... [详细]
  • 本文详细介绍了Java编程语言中的核心概念和常见面试问题,包括集合类、数据结构、线程处理、Java虚拟机(JVM)、HTTP协议以及Git操作等方面的内容。通过深入分析每个主题,帮助读者更好地理解Java的关键特性和最佳实践。 ... [详细]
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社区 版权所有