并发编程:自定义并发类:5、自定义周期调度任务

Swift语言的并发编程 Swift的并发编程是一个强大且必要的特性,它让开发者以更直观的方式处理异步任务。这种新模型不仅简化了代码的结构,提高了开发效率,同时也提高了应用的响应速度和性能。随着Swift语言及其并发特性的不断演进,开发者应充分利用这些功能,提升应用的用户体验。希望本文能为在Swift中进行并发编程的开发者提供一些有价值的见解和实用的示例。 阅读详情

目录

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);
	}

	@Override
	protected <V> RunnableScheduledFuture<V> decorateTask(Runnable runnable, RunnableScheduledFuture<V> task) {
		// 该方法会被 schedule、scheduleAtFixedRate、scheduleWithFixedDelay 方法内部调用
		// 这个方法的任务是对原任务进行包装。
		// 包装后的任务必须是实现RunnableScheduledFuture接口的类(因为线程池需要判断是否是周期任务)
		return new MyScheduledTask<V>(runnable, null, task, this);
	}

	@Override
	public 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<V> extends FutureTask<V> implements RunnableScheduledFuture<V> {
	// 原任务
	private RunnableScheduledFuture<V> task;
	// 线程池
	private ScheduledThreadPoolExecutor executor;
	// 运行周期
	private long period;
	// 用于周期任务(开始执行的时间)
	private long startDate;

	public MyScheduledTask(Runnable runnable, V result, RunnableScheduledFuture<V> task,
			ScheduledThreadPoolExecutor executor) {
		super(runnable, result);
		this.task = task;
		this.executor = executor;
	}

	@Override
	public 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;
			}
		}
	}

	@Override
	public int compareTo(Delayed o) {
		return task.compareTo(o);
	}

	@Override
	public boolean isPeriodic() {
		return task.isPeriodic();
	}

	@Override
	public 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 {

	@Override
	public 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.

 

并发编程第一阶段 提示:并发编程给我们带来了什么作用可以加快响应用户的时间、使你的代码模块化,异步化,简单化、充分利用CPU的资源提示:以下是本篇文章正文内容,下面案例可供参考Future和FutureTask可以和Callable配合使用Callable的Call方法有返回值,可以声明抛出异常Future对具体的Runnable或者Callable任务的执行结果进行取消、查询是否完成、获取结果。必要时通过get方法阻塞任务返回结果。Future实际采用FutureTask实现。 阅读详情

相关推荐

【并发编程】线程调度线程池

Java 中 ScheduledExecutorService接口定义调度线程池,newSingleThreadScheduledExecutor类实现了该接口,用于创建一个独立线程的调度线程池。它适合用于需要按计划执行任务的场景,并且任务之间不需要并行。

GM_115的博客 704

【阿里开发规范】ThreadPoolExecutor自定义线程池示例(亲测)

【阿里开发规范】ThreadPoolExecutor自定义线程池示例(亲测)

zss123yq的博客 6537

深入理解 Java 并发编程:从理论到实践的全面指南

《Java并发编程核心技术解析》摘要:本文系统讲解Java并发编程核心知识,涵盖线程基础、内存模型、线程安全三大特性(原子性/可见性/有序性)及volatile/synchronized原理。重点解析并发工具类(线程池/同步容器/闭锁/信号量)的使用场景与实现机制,并深入探讨高级主题如线程通信、原子操作类及并发设计模式。针对死锁、活锁等常见问题提供解决方案,给出减少锁竞争、优化线程池等性能调优策略。通过理论结合实践的方式,帮助开发者掌握编写高效安全并发程序的技能,适应多核处理器时代的开发需求。

2503_91057718的博客 1140

基于ScheduledThreadPoolExecutor线程池的周期性任务、延时自定义封装

基于ScheduledThreadPoolExecutor线程池的周期性任务、延时自定义封装

qq_36365860的博客 620

【Java学习】5个状态揭秘线程生命周期:并发编程的深度解析与实战指南

🔥关注墨瑾轩,带你探索编程的奥秘!🚀🔥超萌技术攻略,轻松晋级编程高手🚀🔥技术宝库已备好,就等你来挖掘🚀🔥订阅墨瑾轩,智趣学习不孤单🚀🔥即刻启航,编程之旅更有趣🚀。

java专栏 1303

CST软件中SPICE模型的高效导出与转换技巧(txt到cir实战指南)

本文详细介绍了在CST Studio Suite中高效导出与转换SPICE模型的实战技巧,重点讲解了如何将txt格式的模型转换为通用的cir格式。内容涵盖三种模型存在形式的处理方法、格式检查与内容清理、端口一致性验证等关键步骤,并提供了利用LTspice Export功能、批处理脚本以及结果一致性校验等进阶指南,帮助工程师实现场路协同仿真模型的无缝迁移与应用。

silver的专栏 1183

Java ExecutorService 中的 `awaitTermination()` 原理

如果在指定时间内未完成所有任务,可以选择调用 shutdownNow() 来强制关闭正在执行的任务。:时间单位,如 TimeUnit.SECONDS、TimeUnit.MILLISECONDS 等。抛出异常:InterruptedException,当等待过程被中断时抛出。:最大等待时间,表示阻塞等待的时长。:所有任务在规定时间内已执行完毕。:超时仍有任务未完成。

weixin_45535978的博客 1488

FreeRTOS面试题汇总

如果一个低优先级的任务持有一个信号量,高优先级的任务想要用这个信号量,造成的死锁怎么解决。12.FreeRTOS的多任务之间如何去进行通信的,什么方法,它实现原理是什么。任务间数据传输一共有三种形式,用的最多的是消息队列,其次是全局变量和信号量。简历上写了了解RTOS,问了rtos的问题,用过哪些函数。讲解FreeRtos原理,调度机制,底层原理,代码调用。FreeRTOS,你的三个任务控制,请问你是怎么实现的。freertos中EventBits_t是干啥的?freertos使任务切换的方式有哪些?

weixin_45636780的博客 1万+

Java自定义线程池-ThreadPoolExecutor

Java-ThreadPoolExecutor自定义线程池

致终将逝去的编程青春 1774

博科的SAN交换机基本操作

2、添加用户testuser赋予user权限可以访问1-128VF默认VF为128账号描述"Test user"密码为password123。1、创建zone别名(100是指当前设备Domain ID,1和2是指对应的index号)2,删除新接入设备的ZONE或保持ZONE配置一致。3、将zone添加到当前生效的CFG中。2、将zone添加到当前生效的CFG中。3、将zone添加到当前生效的CFG中。3,将添加的级联端口持续关闭。4、将当前zone生效。4、将当前zone生效。1、查看当前所有用户。

chenjunokok的博客 1837

NVIDIA显卡驱动历史版本全攻略:从官网隐藏入口到精准下载

本文详细介绍了如何获取NVIDIA显卡驱动历史版本的完整攻略,包括官网隐藏入口的揭秘、精准筛选驱动版本的技巧以及安装避坑指南。特别针对游戏玩家、创作者和老显卡用户提供了实用建议,帮助用户解决驱动兼容性问题,提升显卡性能。

m2n3o4p5的博客 3718

JAVA多线程问题 — 基于Executor自定义线程池内的延迟和周期性任务

基于 Executor自定义线程池内的延迟和周期性任务 基于 Executor自定义线程池内的延迟和周期性任务,它通过 ScheduledThreadPoolExecutor 类来实现,并允许运行以下这两种任务: Delayed 任务:延迟运行一个任务 Executor框架提供ThreadPoolExecutor类,使用池中的线程来执行Callable和Runnable任务,这样可以避免所有线程的创建操作。当你提交一个任务给执行者,会根据执行者的配置尽快执行它。在有些使用情况下,当你对尽快执行任务不感觉兴

qq_38658567的博客 1144

SpringCloud2025+SpringBoot3.5.0+gateway+webflux子服务路由报503

本来昨天就应该也记录下,免得忘记的,但是有点晚了,酒没写,真的是被坑惨了。当然这也是追求最新的代价,也是对新技术、老知识点的重温。依赖更粒度让架构的知识面更高,需要非常清楚另外说不定是有新的负载均衡要出现了,就想当初loadbalancer取代Ribbon一样好了,真是坑了半夜,昨晚都没有写,今天才复盘,希望能帮到大家,让更多在坑里的技术人爬出来。

zwrlj527的专栏 1996

Go并发编程实践:WatchYourLAN扫描任务调度机制

在现代网络管理中,实时IP扫描是保障网络安全与监控的关键环节。传统扫描工具常面临**资源占用过高**、**响应延迟**和**任务调度混乱**三大痛点。WatchYourLAN作为轻量级网络IP扫描工具(Lightweight network IP scanner with web GUI),基于Go语言实现了高效的并发任务调度机制,通过goroutine与channel的精妙配合,将扫描任务的CP...

gitblog_00229的博客 903

RK3568平台(电源篇)电源域IO配置

在kernel之前需要修改电源域,主控电源域的IO电平要与对接外设芯片的IO电平匹配,还要注意软件的电压配置要跟硬件的电压一致,否则,最坏的情况可能会导致IO的损坏。其实就是管理 IO 输出的电平;假如硬件上 IO 电源域配置为 3.3V,则 IO 输出最大电平为 3.3V;同理 IO 电源域硬件配置为 1.8V,则 IO 输出最大电平是 1.8V;这样有利于 IO 电平的灵活配置;

weixin_49303682的博客 3478

【DRAM存储器六十二】DDR5介绍--引脚和基本功能简介

详述DDR5与DDR4的引脚区别和DDR5基本功能

highman110的博客 523

【仓颉实战】高性能并发编程:协程、通道与分布式任务调度

本文深入探讨仓颉语言的高性能并发编程范式,重点介绍协程、通道通信和分布式任务调度等核心技术。文章包含以下核心内容: 并发基础:对比并发与并行概念,解析仓颉的CSP模型设计哲学 协程机制:详解轻量级协程的创建、生命周期管理及状态转换 通信模型:通过通道实现安全高效的协程间通信 实战应用:构建分布式Web爬虫系统,展示架构设计与性能优化 关键特性包括: 用户级协程调度(ns级切换) 类型安全的通道通信 分布式任务调度器 高性能并发安全机制 通过代码示例展示了协程创建、状态管理和错误处理的最佳实践,为构建高并发系

2302_80663569的博客 1198

【2023校招刷题】第二期:数字IC笔试模拟题(2)详细解析版

【2023校招刷题】第二期:数字IC笔试模拟题(2)详细解析版

悟已往之不谏 知来者之可追 4469

关于Java并发编程的总结和思考

编写优质的并发代码是一件难度极高的事情。Java语言从第一版本开始内置了对多线程的支持,这一点在当年是非常了不起的,但是当我们对并发编程有了更深刻的认识和更多的实践后,实现并发编程就有了更多的方案和更好的选择。本文是对并发编程的一点总结和思考,同时也分享了Java 5以后的版本中如何编写并发代码的一点点经验。

骆昊的技术专栏 16万+

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

并发编程:Java高效多线程实战指南

并发编程是现代软件开发中的关键技术,尤其在Java中,它通过多线程机制实现任务的高效执行。并发与并行的主要区别在于任务执行方式:并发是任务交替执行,适用于单核CPU;并行是任务同时执行,依赖多核CPU。

m0_71744084的博客 2880

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

玩转-并发编程

使用线程池,可以复用线程及控制线程的总量。如果不使用线程池,每个任务都要新开一个线程来处理,反复创建线程开销大,过多的线程会占用太多内存。ThreadLocal 为每个线程维护一个本地变量。采用空间换时间,它用于线程间的数据隔离,为每一个使用该变量的线程提供一个 副本,每个线程都可以独立地改变自己的副本,而不会和其他线程的副本突。ThreadLocal 类中维护一个 Map,用于存储每一个线程的变量副本,Map 中元素的键为线程对象,而值为对应线程的变量副本。

yinbaoli的博客 1518

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

Java并发编程

并发:同时有多个请求并发执行:在一个时间段内对多个请求依次执行并行执行:在一个时间点上,有多个任务同时执行并发编程:在用户高并发访问场景下(卖票,秒杀,抢购),我们要让程序并发执行本质解决的就是多线程对共享资源的访问出现的问题JMM为每个线程设置了内存(工作内存)作为高速缓存,导致的不可见性问题,编译优化带来的乱序性问题,线程切换带来的非原子性问题其实缓存、线程、编译优化的目的和我们写并发程序的目的是相同的,都是提高程序安全性和性能。

Vaclee的博客 818

java并发编程

什么是java并发编程如何进行并发编程

m0_64021225的博客 1724

【JUC并发编程】5 定时任务线程池ScheduledThreadPoolExecutor的使用

ScheduledThreadPoolExecutor介绍 ScheduledThreadPoolExecutor继承自ThreadPoolExecutor。它主要用来在给定的延迟之后执行任务,或者定期执行任务。通常使用工厂类Executors来创建。 ScheduledThreadPoolExecutor的功能与Timer类似,但比Timer更强大,更灵活,Timer对应的是单个后台线程,而ScheduledThreadPoolExecutor可以在构造函数中指定多个对应的后台线程数。 2.Sc

健身变秃,coding变强 1万+

并发编程的挑战

学以致用,方得始终。

qq_38248841的博客 1万+
上一篇: 并发编程:自定义并发类:3、使用指定的线程工厂创建线程池
下一篇: 并发编程:自定义并发类:6、自定义的fork/join线程类(拓展ForkJoinWorkerThread)
博风
博客等级 码龄16年 442粉丝 357原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值