Timer 和 ScheduledExecutor 都仅能提供基于开始时间与重复间隔的任务调度,不能胜任更加复杂的调度需求。比如,设置每星期二的 16:38:10 执行任务。该功能使用 Timer 和 ScheduledExecutor 都不能直接实现,但我们可以借助 Calendar 间接实现该功能。
清单 3. 使用 ScheduledExcetuor 和 Calendar 进行任务调度
package com.ibm.scheduler; import java.util.Calendar; import java.util.Date; import java.util.TimerTask; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; public class ScheduledExceutorTest2 extends TimerTask { private String jobName = ""; public ScheduledExceutorTest2(String jobName) { super(); this.jobName = jobName; } @Override public void run() { System.out.println("Date = "+new Date()+", execute " + jobName); } /** * 计算从当前时间currentDate开始,满足条件dayOfWeek, hourOfDay, * minuteOfHour, secondOfMinite的最近时间 * @return */ public Calendar getEarliestDate(Calendar currentDate, int dayOfWeek, int hourOfDay, int minuteOfHour, int secondOfMinite) { //计算当前时间的WEEK_OF_YEAR,DAY_OF_WEEK, HOUR_OF_DAY, MINUTE,SECOND等各个字段值 int currentWeekOfYear = currentDate.get(Calendar.WEEK_OF_YEAR); int currentDayOfWeek = currentDate.get(Calendar.DAY_OF_WEEK); int currentHour = currentDate.get(Calendar.HOUR_OF_DAY); int currentMinute = currentDate.get(Calendar.MINUTE); int currentSecond = currentDate.get(Calendar.SECOND); //如果输入条件中的dayOfWeek小于当前日期的dayOfWeek,则WEEK_OF_YEAR需要推迟一周 boolean weekLater = false; if (dayOfWeek < currentDayOfWeek) { weekLater = true; } else if (dayOfWeek == currentDayOfWeek) { //当输入条件与当前日期的dayOfWeek相等时,如果输入条件中的 //hourOfDay小于当前日期的 //currentHour,则WEEK_OF_YEAR需要推迟一周 if (hourOfDay < currentHour) { weekLater = true; } else if (hourOfDay == currentHour) { //当输入条件与当前日期的dayOfWeek, hourOfDay相等时, //如果输入条件中的minuteOfHour小于当前日期的 //currentMinute,则WEEK_OF_YEAR需要推迟一周 if (minuteOfHour < currentMinute) { weekLater = true; } else if (minuteOfHour == currentSecond) { //当输入条件与当前日期的dayOfWeek, hourOfDay, //minuteOfHour相等时,如果输入条件中的 //secondOfMinite小于当前日期的currentSecond, //则WEEK_OF_YEAR需要推迟一周 if (secondOfMinite < currentSecond) { weekLater = true; } } } } if (weekLater) { //设置当前日期中的WEEK_OF_YEAR为当前周推迟一周 currentDate.set(Calendar.WEEK_OF_YEAR, currentWeekOfYear + 1); } // 设置当前日期中的DAY_OF_WEEK,HOUR_OF_DAY,MINUTE,SECOND为输入条件中的值。 currentDate.set(Calendar.DAY_OF_WEEK, dayOfWeek); currentDate.set(Calendar.HOUR_OF_DAY, hourOfDay); currentDate.set(Calendar.MINUTE, minuteOfHour); currentDate.set(Calendar.SECOND, secondOfMinite); return currentDate; } public static void main(String[] args) throws Exception { ScheduledExceutorTest2 test = new ScheduledExceutorTest2("job1"); //获取当前时间 Calendar currentDate = Calendar.getInstance(); long currentDateLong = currentDate.getTime().getTime(); System.out.println("Current Date = " + currentDate.getTime().toString()); //计算满足条件的最近一次执行时间 Calendar earliestDate = test .getEarliestDate(currentDate, 3, 16, 38, 10); long earliestDateLong = earliestDate.getTime().getTime(); System.out.println("Earliest Date = " + earliestDate.getTime().toString()); //计算从当前时间到最近一次执行时间的时间间隔 long delay = earliestDateLong - currentDateLong; //计算执行周期为一星期 long period = 7 * 24 * 60 * 60 * 1000; ScheduledExecutorService service = Executors.newScheduledThreadPool(10); //从现在开始delay毫秒之后,每隔一星期执行一次job1 service.scheduleAtFixedRate(test, delay, period, TimeUnit.MILLISECONDS); } } Output: Current Date = Wed Feb 02 17:32:01 CST 2011 Earliest Date = Tue Feb 8 16:38:10 CST 2011 Date = Tue Feb 8 16:38:10 CST 2011, execute job1 Date = Tue Feb 15 16:38:10 CST 2011, execute job1
实现了每星期二 16:38:10 调度任务的功能。其核心在于根据当前时间推算出最近一个星期二 16:38:10 的绝对时间,然后计算与当前时间的时间差,作为调用 ScheduledExceutor 函数的参数。计算最近时间要用到 java.util.calendar 的功能。首先需要解释 calendar 的一些设计思想。Calendar 有以下几种唯一标识一个日期的组合方式:
YEAR + MONTH + DAY_OF_MONTH YEAR + MONTH + WEEK_OF_MONTH + DAY_OF_WEEK YEAR + MONTH + DAY_OF_WEEK_IN_MONTH + DAY_OF_WEEK YEAR + DAY_OF_YEAR YEAR + DAY_OF_WEEK + WEEK_OF_YEAR |
上述组合分别加上 HOUR_OF_DAY + MINUTE + SECOND 即为一个完整的时间标识。本例采用了最后一种组合方式。输入为 DAY_OF_WEEK, HOUR_OF_DAY, MINUTE, SECOND 以及当前日期 , 输出为一个满足 DAY_OF_WEEK, HOUR_OF_DAY, MINUTE, SECOND 并且距离当前日期最近的未来日期。计算的原则是从输入的 DAY_OF_WEEK 开始比较,如果小于当前日期的 DAY_OF_WEEK,则需要向 WEEK_OF_YEAR 进一, 即将当前日期中的 WEEK_OF_YEAR 加一并覆盖旧值;如果等于当前的 DAY_OF_WEEK, 则继续比较 HOUR_OF_DAY;如果大于当前的 DAY_OF_WEEK,则直接调用 java.util.calenda 的 calendar.set(field, value) 函数将当前日期的 DAY_OF_WEEK, HOUR_OF_DAY, MINUTE, SECOND 赋值为输入值,依次类推,直到比较至 SECOND。读者可以根据输入需求选择不同的组合方式来计算最近执行时间。
相关推荐
在实现复杂任务调度时,有时需要结合使用`Calendar`类。`Calendar`是Java中的日期和时间类,可以用来精确地计算和设置时间点,比如设定任务的执行时间。通过`Calendar`,开发者可以创建精确到秒甚至毫秒的调度规则,...
本文由浅入深介绍四种任务调度的Java实现:ScheduledExecutor开源工具包Quartz开源工具包JCronTab此外,为结合实现复杂的任务调度,本文还将介绍Calendar的一些使用方法。Timer相信大家都已经非常熟悉java.util....
内容概要:本文介绍了一种基于Retinex模型和多尺度融合的低光照图像增强算法。首先,通过对原图像进行光照图分解并利用Retinex模型进行估计,再经过伽马矫正获得亮度均衡的图像。接着,为补偿伽马矫正当中的过曝细节丢失,进行了锐化处理以提升图像细节。最后,在多尺度融合金字塔模型下,根据不同输入图像的权重进行融合,从而得到最终的增强图像。文中还详细介绍了五个非参考图像质量评价指标(BRISQUE,CEIQ,ENIQA,NIQE,PIQE),用以评估算法的效果。 适合人群:从事计算机视觉、图像处理领域的研究人员和技术人员。 使用场景及目标:适用于需要在低光照条件下获取高质量图像的各种应用场景,如安防监控、自动驾驶、医疗影像等领域。目的是提高图像的亮度、对比度和细节,确保后续图像处理任务的有效性和准确性。 其他说明:该算法不仅提高了低光照环境拍摄照片的质量,也为其他计算机视觉应用提供了更好的图像素材,具有重要的社会和经济价值。
scratch少儿编程逻辑思维游戏源码-奔跑吧!忍者.zip
内容概要:本文详细介绍了基于人工蜂群算法的路径规划系统。该算法模拟蜜蜂觅食行为,通过多个个体的并行搜索,实现了全局搜索能力强、鲁棒性和适应性强、适用范围广、算法设计灵活以及具有分布式计算能力等特点。文中还提供了简化的代码片段,展示了如何实现地图创建、保存和起始地点更改等功能,进一步解释了算法的具体实现方法。 适合人群:对路径规划算法感兴趣的科研人员、工程师和技术爱好者。 使用场景及目标:适用于复杂环境下的单目标或多目标路径规划问题,旨在帮助研究人员和开发者更好地理解和应用人工蜂群算法,提升路径规划系统的性能和效率。 其他说明:该算法不仅在理论上具有较高的研究价值,还在实际应用中展现了广泛的潜力,特别是在智能交通、机器人导航等领域。
内容概要:本文介绍了如何使用鲸鱼算法优化最小二乘支持向量机(LSSVM)的回归预测模型。通过模拟鲸鱼群体的行为,优化LSSVM中的惩罚参数和核惩罚参数,提高了预测的准确性和可靠性。鲸鱼算法具有广泛的适用性、强大的全局优化能力和高效的计算特点,使其成为解决各类回归预测问题的有效工具。文中还提供了具体的Python代码实现,展示了从基本LSSVM预测到参数优化的具体步骤,并通过实验数据验证了优化后的模型在训练时间和预测精度上的显著优势。 适合人群:对机器学习、优化算法感兴趣的开发者和技术研究人员,尤其是希望深入了解和支持向量机优化的人群。 使用场景及目标:适用于需要提高回归预测准确性的应用场景,如金融预测、气象预报等领域。目标是通过优化模型参数,获得更高的预测精度和更快的计算速度。 其他说明:鲸鱼算法不仅在理论上具有优越性,在实际应用中也能显著提升模型性能。建议根据具体的数据规模调整算法参数,以达到最佳效果。
scratch少儿编程逻辑思维游戏源码-超级猫.zip
scratch少儿编程逻辑思维游戏源码-超级马里奥世界 多人游戏.zip
scratch少儿编程逻辑思维游戏源码-丛林探险跑酷.zip
【java】智能自助式停车场管理系统后台web管理服务器javaweb项目
内容概要:本文详细介绍了二阶系统的PID控制器设计与仿真方法,展示了如何通过MATLAB进行系统建模和控制器参数调整。首先构建了一个典型的二阶系统作为例子,通过设置不同的PID参数(比例P、积分I、微分D),演示了如何优化系统的阶跃响应特性。文中还讨论了不同参数对系统稳定性的影响,以及如何应对非线性环节带来的挑战。此外,作者强调了PID控制器参数调整的重要性,并提供了几种实用技巧,如使用MATLAB内置工具pidTuner进行参数整定,以及尝试更换不同的被控对象来测试控制器的适应性和鲁棒性。 适合人群:自动化工程专业学生、从事工业控制系统设计的技术人员、对PID控制感兴趣的科研工作者。 使用场景及目标:① 学习如何利用MATLAB搭建二阶系统并设计PID控制器;② 掌握PID参数调整的基本方法及其对系统性能的影响;③ 提升解决实际工业控制问题的能力,特别是在面对复杂动态环境时。 阅读建议:读者可以通过跟随文中的步骤,在自己的环境中重现实验结果,从而加深对PID控制理论的理解。同时,鼓励读者尝试修改系统参数或引入新的干扰因素,进一步探索PID控制器的应用边界。
少儿编程scratch项目源代码文件案例素材-扫雷.zip
少儿编程scratch项目源代码文件案例素材-圣诞老人VS机器人.zip
【基于AT89C51单片机的交通灯系统】是电子工程领域中的一个经典实践项目,尤其适合初学者进行单片机编程和硬件控制的学习。AT89C51是一款广泛应用的8位微处理器,由美国Atmel公司生产,具有4KB的可编程Flash存储器,可以执行各种控制任务,包括交通灯系统的控制。 交通灯控制系统是城市交通管理的重要组成部分,通过红绿黄三色灯的变化来指示行人和车辆何时通行。在本项目中,交通灯系统采用AT89C51单片机作为核心控制器,通过编程实现红绿黄灯的定时切换,确保交通流畅且安全。 DSN(Design Suite Notation)文件,如`C51交通灯.DSN`,通常是在电路设计软件,如Keil uVision或Proteus中创建的工程文件。这种文件包含了整个项目的配置信息,包括源代码、元器件库、仿真设置等,使得开发者可以在虚拟环境中对交通灯系统进行仿真测试。Proteus是一款强大的电子电路仿真软件,可以直观地模拟硬件电路的行为,无需物理硬件即可验证设计的正确性。 数码管(7段显示器)是显示倒计时的关键部件。在这个项目中,数码管用于显示每个灯组的剩余时间,增强用户交互体验,使驾驶员和行人能够清晰了解何时转换灯色。AT89C51通过串行或并行接口与数码管连接,并通过特定的驱动程序代码控制数码管的显示内容。 编程方面,AT89C51使用C51语言编写,这是一种为8051系列单片机定制的C语言变体。代码中包含的详细注释对于初学者理解程序逻辑至关重要,通过注释可以学习如何设置定时器、中断服务子程序以及I/O端口操作,这些都是单片机编程的基础知识。 交通灯的控制通常基于定时器中断,例如,可以设置一个定时器在特定周期后触发中断,然后在中断服务程序中改变灯的状态。此外,为了实现数码管显示,可能需要用到移位寄存器和译码器等外围设备,这些都需要在代码中进行编程控制。 这个项目涵
内容概要:本文介绍了一种基于MATLAB的改进带记忆模拟退火算法用于求解旅行商问题(TSP)。该算法引入了多普勒型降温曲线和记忆功能,使得算法在前期进行全局搜索而在后期进行精细调整。文中详细展示了算法的核心代码片段,如多普勒型降温曲线的实现和记忆功能的具体实现方式。此外,作者提供了对多个经典数据集(如att48、中国31/64/144城市数据)的测试结果,证明了该算法的有效性和优越性。同时,还给出了自定义数据集的测试方法和路径可视化的代码。 适合人群:对优化算法感兴趣的研究人员和技术爱好者,尤其是那些希望深入了解模拟退火算法及其应用的人群。 使用场景及目标:适用于需要解决复杂组合优化问题的场景,特别是涉及路径规划、物流配送等领域。目标是提供一种高效、稳定的解决方案,帮助用户快速获得高质量的解。 其他说明:本文不仅提供了完整的代码实现,还包括详细的解释和测试实例,便于读者理解和实践。对于想要进一步探索或修改算法的人来说,这是一个很好的起点。
内容概要:本文详细介绍了MMC-HVDC电能质量调节系统及其背靠背模块化多电平换流器(MMC)的工作原理和技术优势。MMC-HVDC系统主要用于保护敏感电网免受瞬态电压骤降的影响,通过内部能量存储和整流器控制线路电流,确保电网的稳定性。此外,该系统还具备无功功率补偿、低谐波失真和高冗余性的特点。文中特别提到MMC-HVDC在粒子加速器领域的应用和发展前景,强调了其在复杂环境中的适应性和可靠性。 适合人群:从事电力系统工程、电能质量管理、粒子加速器设计的研究人员和技术人员。 使用场景及目标:适用于需要解决瞬态电压骤降问题的电力系统,特别是在粒子加速器等对电能质量有较高要求的场合。目标是提高电网的稳定性和效率,减少设备损坏和系统不稳定性。 其他说明:文章还讨论了MMC-HVDC的设计和开发过程,包括模块化结构设计、能量存储优化和控制算法改进等方面的内容。
少儿编程scratch项目源代码文件案例素材-侵略者.zip
scratch少儿编程逻辑思维游戏源码-暴徒危机.zip
少儿编程scratch项目源代码文件案例素材-收缩剑.zip
少儿编程scratch项目源代码文件案例素材-忍者传奇.zip