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

 


推荐阅读
  • 并发编程 12—— 任务取消与关闭 之 shutdownNow 的局限性
    Java并发编程实践目录并发编程01——ThreadLocal并发编程02——ConcurrentHashMap并发编程03——阻塞队列和生产者-消费者模式并发编程04——闭锁Co ... [详细]
  • 深入解析动态代理模式:23种设计模式之三
    在设计模式中,动态代理模式是应用最为广泛的一种代理模式。它允许我们在运行时动态创建代理对象,并在调用方法时进行增强处理。本文将详细介绍动态代理的实现机制及其应用场景。 ... [详细]
  • Java多线程实现:从1到100分段求和并汇总结果
    本文介绍如何使用Java编写一个程序,通过10个线程分别计算不同区间的和,并最终汇总所有线程的结果。每个线程负责计算一段连续的整数之和,最后将所有线程的结果相加。 ... [详细]
  • Linux环境下进程间通信:深入解析信号机制
    本文详细探讨了Linux系统中信号的生命周期,从信号生成到处理函数执行完毕的全过程,并介绍了信号编程中的注意事项和常见应用实例。通过分析信号在进程中的注册、注销及处理过程,帮助读者理解如何高效利用信号进行进程间通信。 ... [详细]
  • 深入解析Java多线程与并发库的应用:空中网实习生面试题详解
    本文详细探讨了Java多线程与并发库的高级应用,结合空中网在挑选实习生时的面试题目,深入分析了相关技术要点和实现细节。文章通过具体的代码示例展示了如何使用Semaphore和SynchronousQueue来管理线程同步和任务调度。 ... [详细]
  • 深入理解Java多线程并发处理:基础与实践
    本文探讨了Java中的多线程并发处理机制,从基本概念到实际应用,帮助读者全面理解并掌握多线程编程技巧。通过实例解析和理论阐述,确保初学者也能轻松入门。 ... [详细]
  • 2017-2018年度《网络编程与安全》第五次实验报告
    本报告详细记录了2017-2018学年《网络编程与安全》课程第五次实验的具体内容、实验过程、遇到的问题及解决方案。 ... [详细]
  • 深入解析SpringMVC核心组件:DispatcherServlet的工作原理
    本文详细探讨了SpringMVC的核心组件——DispatcherServlet的运作机制,旨在帮助有一定Java和Spring基础的开发人员理解HTTP请求是如何被映射到Controller并执行的。文章将解答以下问题:1. HTTP请求如何映射到Controller;2. Controller是如何被执行的。 ... [详细]
  • 本文介绍 Java 中如何使用 Year 类的 atMonth 方法将年份和月份组合成 YearMonth 对象,并提供代码示例。 ... [详细]
  • 深入解析ArrayList与LinkedList的差异
    本文详细对比了Java中ArrayList和LinkedList两种常用集合类的特性、性能及适用场景,通过代码示例进行测试,并结合实际应用场景分析其优缺点。 ... [详细]
  • 本文深入探讨了 Java 中 LocalTime 类的 isSupported() 方法,包括其功能、语法和使用示例。通过具体的代码片段,帮助读者理解如何检查特定的时间字段或单位是否被 LocalTime 类支持。 ... [详细]
  • 本文详细介绍了装饰者(Decorator)模式,这是一种动态地为对象添加职责的方法。与传统的继承方式不同,装饰者模式通过组合而非继承来实现功能扩展,从而提供更大的灵活性和可维护性。 ... [详细]
  • 为了解决不同服务器间共享图片的需求,我们最初考虑建立一个FTP图片服务器。然而,考虑到项目是一个简单的CMS系统,为了简化流程,团队决定探索七牛云存储的解决方案。本文将详细介绍使用七牛云存储的过程和心得。 ... [详细]
  • 深入解析 Android IPC 中的 Messenger 机制
    本文详细介绍了 Android 中基于消息传递的进程间通信(IPC)机制——Messenger。通过实例和源码分析,帮助开发者更好地理解和使用这一高效的通信工具。 ... [详细]
  • 本文探讨了如何通过一系列技术手段提升Spring Boot项目的并发处理能力,解决生产环境中因慢请求导致的系统性能下降问题。 ... [详细]
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社区 版权所有