springframework.scheduling.quartz工作调度器使用(三)-自定义多线程池任务

实现场景一:

      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,导致出现服务器出现大量的多线程池。





猜你喜欢

转载自blog.csdn.net/jun55xiu/article/details/79929976