实现场景一:
1)任务在频率H1(30秒)定时执行,频率内任务执行所需时间超过频率时间段(30秒),出现频率内任务未执行完成,被下一次执行的任务中途中断的情况;
2) 第二个30秒时间节点(即下一频率)调度任务时,由于无空闲线程(上一频率任务占用全部线程),出现当前调度任务内的线程大量等待,导致第二个30秒时间节点调度任务执行的工作廷迟。 <即:“springframework.scheduling.quartz工作调度器使用(二)-自定义多线程池任务” 遇到的问题>
目 的:为解决 实现场景一 任务在执行过程中被中断,出现数据丢失的问题和情况 以及 下一频率调度任务开始执行任务工作廷迟等问题。
方 案 二:
springframework.scheduling.quartz工作调度器配置任务调度+后台定义多线程池java.util.concurrent.ThreadPoolExecutor
配置文件:(只配置调度的执行任务)
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xmlns:task="http://www.springframework.org/schema/task" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd " default-lazy-init="false"> <bean id="configholder" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> </bean> <context:annotation-config /> <tx:annotation-driven proxy-target-class="true" /> <bean id="ruleService" class="com.hp.bon.omc.nms.core.threadPool.RuleService2"></bean> <!-- 定时 --> <bean id="ruleBean" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"> <property name="targetObject" ref="ruleService" /> <property name="targetMethod" value="updateRule" /> <property name="concurrent" value="false" /> </bean> <bean id="rule" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean"> <property name="jobDetail" ref="ruleBean" /> <!-- 每30秒 执行 --> <property name="cronExpression" value="0/30 * * * * ?"/> </bean> <!-- 定时 end --> <bean id="startQuertz" lazy-init="false" autowire="no" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <property name="jobDetails"> <list> <ref bean="ruleBean" /> </list> </property> <property name="triggers"> <list> <ref bean="rule" /> </list> </property> <!-- 启动时延期10秒开始任务 --> <property name="startupDelay" value="10" /> </bean> </beans>
任务调度类:RuleService2
package com.hp.bon.omc.nms.core.threadPool; import java.util.ArrayList; import java.util.List; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import org.springframework.stereotype.Service; @Service public class RuleService2 { private static final Logger LOG = LoggerFactory.getLogger(RuleService2.class); public void updateRule() { updateRuleWithThreadPoolExecutor(); } public void updateRuleWithThreadPoolExecutor() { LOG.info("任务已经调度,服务RuleService2已开始执行........"); BlockingQueue<Runnable> queue = new LinkedBlockingQueue<Runnable>(300); ThreadPoolExecutor executor = new ThreadPoolExecutor(5, 10, 60,TimeUnit.SECONDS, queue); executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); List<String> strList = new ArrayList<String>(); for (int i = 0; i < 30; i++) { strList.add("test" + i); } for (int i = 0; i < strList.size(); i++) { executor.execute(new Thread(new StartTaskThread2(strList.get(i)), "TestThread".concat(""+i))); } } }
后台定义多线程池java.util.concurrent.ThreadPoolExecutor:(执行调度任务的具体工作)
BlockingQueue<Runnable> queue = new LinkedBlockingQueue<Runnable>(300);
ThreadPoolExecutor executor = new ThreadPoolExecutor(5, 10, 60,TimeUnit.SECONDS, queue);
自定义线程处理类StartTaskThread2类:同“springframework.scheduling.quartz工作调度器使用(二)-自定义多线程池任务” 中一致
输 出:
<!--第一次任务调度:pool-1线程池启动5个线程,每间隔8秒执行一次任务队列中任务,执行完成 20个任务-->
2018-04-13 15:44:30.034 INFO [startQuertz_Worker-1] - 任务已经调度,服务RuleService2已开始执行........
2018-04-13 15:44:30.039 INFO [pool-1-thread-1] - Time:2018-04-13 15:44:30...st=test0
2018-04-13 15:44:30.040 INFO [pool-1-thread-2] - Time:2018-04-13 15:44:30...st=test1
2018-04-13 15:44:30.042 INFO [pool-1-thread-3] - Time:2018-04-13 15:44:30...st=test2
2018-04-13 15:44:30.044 INFO [pool-1-thread-4] - Time:2018-04-13 15:44:30...st=test3
2018-04-13 15:44:30.045 INFO [pool-1-thread-5] - Time:2018-04-13 15:44:30...st=test4
2018-04-13 15:44:38.041 INFO [pool-1-thread-1] - Time:2018-04-13 15:44:38...st=test5
2018-04-13 15:44:38.042 INFO [pool-1-thread-2] - Time:2018-04-13 15:44:38...st=test6
2018-04-13 15:44:38.043 INFO [pool-1-thread-3] - Time:2018-04-13 15:44:38...st=test7
2018-04-13 15:44:38.046 INFO [pool-1-thread-4] - Time:2018-04-13 15:44:38...st=test8
2018-04-13 15:44:38.047 INFO [pool-1-thread-5] - Time:2018-04-13 15:44:38...st=test9
2018-04-13 15:44:46.127 INFO [pool-1-thread-2] - Time:2018-04-13 15:44:46...st=test10
2018-04-13 15:44:46.127 INFO [pool-1-thread-3] - Time:2018-04-13 15:44:46...st=test11
2018-04-13 15:44:46.161 INFO [pool-1-thread-1] - Time:2018-04-13 15:44:46...st=test12
2018-04-13 15:44:46.164 INFO [pool-1-thread-4] - Time:2018-04-13 15:44:46...st=test13
2018-04-13 15:44:46.164 INFO [pool-1-thread-5] - Time:2018-04-13 15:44:46...st=test14
2018-04-13 15:44:54.128 INFO [pool-1-thread-2] - Time:2018-04-13 15:44:54...st=test15
2018-04-13 15:44:54.129 INFO [pool-1-thread-3] - Time:2018-04-13 15:44:54...st=test16
2018-04-13 15:44:54.163 INFO [pool-1-thread-1] - Time:2018-04-13 15:44:54...st=test17
2018-04-13 15:44:54.165 INFO [pool-1-thread-4] - Time:2018-04-13 15:44:54...st=test18
2018-04-13 15:44:54.166 INFO [pool-1-thread-5] - Time:2018-04-13 15:44:54...st=test19
<!--第二次任务调度:
pool-2线程池启动5个线程,每间隔8秒执行一次任务队列中任务,执行完成 20个任务;
pool-1线程池等待已有5个线程每隔满8秒释放后,继续执行任务队列中余下的10个任务,直至执行完成30个任务;
-->
2018-04-13 15:45:00.030 INFO [startQuertz_Worker-2] - 任务已经调度,服务RuleService2已开始执行........
2018-04-13 15:45:00.038 INFO [pool-2-thread-3] - Time:2018-04-13 15:45:00...st=test2
2018-04-13 15:45:00.040 INFO [pool-2-thread-4] - Time:2018-04-13 15:45:00...st=test3
2018-04-13 15:45:00.045 INFO [pool-2-thread-1] - Time:2018-04-13 15:45:00...st=test0
2018-04-13 15:45:00.046 INFO [pool-2-thread-2] - Time:2018-04-13 15:45:00...st=test1
2018-04-13 15:45:00.048 INFO [pool-2-thread-5] - Time:2018-04-13 15:45:00...st=test4
2018-04-13 15:45:02.129 INFO [pool-1-thread-3] - Time:2018-04-13 15:45:02...st=test20
2018-04-13 15:45:02.129 INFO [pool-1-thread-2] - Time:2018-04-13 15:45:02...st=test21
2018-04-13 15:45:02.163 INFO [pool-1-thread-1] - Time:2018-04-13 15:45:02...st=test22
2018-04-13 15:45:02.166 INFO [pool-1-thread-4] - Time:2018-04-13 15:45:02...st=test23
2018-04-13 15:45:02.167 INFO [pool-1-thread-5] - Time:2018-04-13 15:45:02...st=test24
2018-04-13 15:45:08.039 INFO [pool-2-thread-3] - Time:2018-04-13 15:45:08...st=test5
2018-04-13 15:45:08.040 INFO [pool-2-thread-4] - Time:2018-04-13 15:45:08...st=test6
2018-04-13 15:45:08.046 INFO [pool-2-thread-1] - Time:2018-04-13 15:45:08...st=test7
2018-04-13 15:45:08.047 INFO [pool-2-thread-2] - Time:2018-04-13 15:45:08...st=test8
2018-04-13 15:45:08.048 INFO [pool-2-thread-5] - Time:2018-04-13 15:45:08...st=test9
2018-04-13 15:45:10.132 INFO [pool-1-thread-2] - Time:2018-04-13 15:45:10...st=test25
2018-04-13 15:45:10.133 INFO [pool-1-thread-3] - Time:2018-04-13 15:45:10...st=test26
2018-04-13 15:45:10.372 INFO [pool-1-thread-5] - Time:2018-04-13 15:45:10...st=test27
2018-04-13 15:45:10.373 INFO [pool-1-thread-4] - Time:2018-04-13 15:45:10...st=test29
2018-04-13 15:45:10.372 INFO [pool-1-thread-1] - Time:2018-04-13 15:45:10...st=test28
2018-04-13 15:45:16.040 INFO [pool-2-thread-3] - Time:2018-04-13 15:45:16...st=test10
2018-04-13 15:45:16.041 INFO [pool-2-thread-4] - Time:2018-04-13 15:45:16...st=test11
2018-04-13 15:45:16.048 INFO [pool-2-thread-1] - Time:2018-04-13 15:45:16...st=test12
2018-04-13 15:45:16.049 INFO [pool-2-thread-2] - Time:2018-04-13 15:45:16...st=test13
2018-04-13 15:45:16.049 INFO [pool-2-thread-5] - Time:2018-04-13 15:45:16...st=test14
2018-04-13 15:45:24.040 INFO [pool-2-thread-3] - Time:2018-04-13 15:45:24...st=test15
2018-04-13 15:45:24.041 INFO [pool-2-thread-4] - Time:2018-04-13 15:45:24...st=test16
2018-04-13 15:45:24.049 INFO [pool-2-thread-2] - Time:2018-04-13 15:45:24...st=test17
2018-04-13 15:45:24.049 INFO [pool-2-thread-1] - Time:2018-04-13 15:45:24...st=test18
2018-04-13 15:45:24.050 INFO [pool-2-thread-5] - Time:2018-04-13 15:45:24...st=test19
<!--第大概次任务调度:执行过程逻辑如上一致
-->
2018-04-13 15:45:30.002 INFO [startQuertz_Worker-3] - 任务已经调度,服务RuleService2已开始执行.....
.....
结 论:
springframework.scheduling.quartz工作调度器 按指定时间 准确地调度任务,任务每次间隔调度时会自定义
线程池java.util.concurrent.ThreadPoolExecutor ,独立完成调度任务内的所有工作。
缺 点:任务每隔一次调用,会重新自定义一个 多线程池java.util.concurrent.ThreadPoolExecutor,导致出现服务器出现大量的多线程池。