spring的Scheduled(定时任务)和多线程
一、前言
在我们日常的开发中,经常用到数据同步的更新,这时我们采用的是spring的定时任务和java的多线程进行数据的更新,进行时实的服务调用。
二.实现思路
1.创建线程类
2.创建ExecutorService线程连接池
3.调用线程池操作
4.spring的Scheduled(定时任务)配置
三.创建线程类
创建的线程类,我们采用的是实现Runnable接口,使用该类可以共享,在线程中要么继承Thread,或者实现Runnable接口,其中Thread是实现了Runnable的接口,实现Runnable接口可以更好的扩展和共享类,因为java是单继承多实现的程序。
public class ArchiveTask implements Runnable {
/**
* log.
*/
private static Logger logger = LoggerFactory.getLogger(ArchiveTask.class);
//注:由于spring事务配置采用的注解的方式来配置传播性配置,此类没有在spring传播配置里面,所以不能用自动装配的方式来配置
private static FaxRecvArchiveCtrl faxRecvArchiveCtrl = AppContextAware.getBean(FaxRecvArchiveCtrl.class);
private FaxRecvArchiveDTO faxRecvArchiveDTO;
/**
* CountDownLatch是一个同步辅助类,在一组线程在执行操作之前,允许一个或多线程处于等待
* 主要方法
* public CountDownLatch(int count);
* public void countDown();
* public void await() throws InterruptedException
*
* 构造方法参数指定了计数的次数
* countDown方法,当前线程调用此方法,则计数减一
* awaint方法,调用此方法会一直阻塞当前线程,直到计时器的值为0
*
*/
private CountDownLatch latch;
public ArchiveTask(FaxRecvArchiveDTO faxRecvArchiveDTO, CountDownLatch latch) {
this.faxRecvArchiveDTO = faxRecvArchiveDTO;
this.latch = latch;
}
@Override
public void run() {
try {
faxRecvArchiveCtrl.updateArchiveFileFlag(ServiceFactory.getCurrentSessionId(), faxRecvArchiveDTO);
} catch (Exception ex) {
logger.debug("["+this.faxRecvArchiveDTO.getFaxKey()+"]线程执行异常,错误信息为:"+ex.getMessage());
} finally{
logger.debug("线程执行完:"+this.faxRecvArchiveDTO.getFaxKey());
latch.countDown();
}
}
}
四、调用线程池操作
public class EasyFaxArchiveFileMgr {
/**
* 日志
*/
Logger logger = LoggerFactory.getLogger(EasyFaxArchiveFileMgr.class);
/**
* 线程池数量
*/
private int ThreadNum = 5;
private static FaxRecvArchiveCtrl faxRecvArchiveCtrl = AppContextAware.getBean(FaxRecvArchiveCtrl.class);
private static List<FaxRecvArchiveDTO> noArchiveList = new ArrayList<FaxRecvArchiveDTO>();
public void archiveFile() throws ShineException{
noArchiveList = faxRecvArchiveCtrl.getFaxRecvNoArchiveFile();
ExecutorService executorService = Executors.newFixedThreadPool(ThreadNum);
List<ArchiveTask> taskList = new ArrayList<ArchiveTask>();
synchronized (noArchiveList) {
while(CollectionUtils.isEmpty(noArchiveList) == false) {
try {
//定义计数器
int countLatch = (noArchiveList.size() > ThreadNum) ? ThreadNum :noArchiveList.size();
CountDownLatch latch = new CountDownLatch(countLatch);
//组织任务
for(int i = 0; i < ThreadNum; i++){
if(CollectionUtils.isEmpty(noArchiveList) == false) {
taskList.add(new ArchiveTask(noArchiveList.remove(0),latch));
}else{
break;
}
}
//提交任务
if (CollectionUtils.isEmpty(taskList) == false) {
for (int i = 0, size = taskList.size(); i < size; i++) {
executorService.submit(taskList.get(i));
}
}//等待所有线程都执行完
latch.await();
} catch(Exception ex) {
logger.error("线程池处理出错,原因:"+ex.getMessage());
} finally {
taskList.clear();
}
//关闭线程连接池
executorService.shutdown();
}
}
}
}
五.spring配置
<?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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd"> <bean id="timerFactory" class="org.springframework.scheduling.timer.TimerFactoryBean">
<property name="scheduledTimerTasks">
<list>
<ref bean="archiveFileScheduler"/>
</list>
</property>
</bean>
<bean id="archiveFileScheduler" class="org.springframework.scheduling.timer.ScheduledTimerTask">
<property name="delay">
<!-- 启动30秒后开始运行 -->
<value>30000</value>
</property>
<property name="period">
<!-- 每10秒运行 -->
<value>10000</value>
</property>
<property name="timerTask">
<ref bean="archiveFileHandleMethodInvoker" />
</property>
</bean> <bean id="archiveFileHandleMethodInvoker" class="org.springframework.scheduling.timer.MethodInvokingTimerTaskFactoryBean">
<property name="targetObject">
<ref bean="com.shine.emofs.thirdparty.easyfax.ctrl.EasyFaxArchiveFileMgr" />
</property>
<property name="targetMethod">
<value>archiveFile</value>
</property>
</bean>
</beans>
六、参考:
ExecutorService线程连接池:http://www.itzhai.com/the-executorservice-common-method-newfixedthreadpool-of-create-fixed-size-thread-pool.html#read-more
spring的Scheduled(定时任务)和多线程的更多相关文章
- Spring Boot Scheduled定时任务特性
SpringBoot中的Scheduled定时任务是Spring Boot中非常常用的特性,用来执行一些比如日切或者日终对账这种定时任务 下面说说使用时要注意的Scheduled的几个特性 Sched ...
- spring的@Scheduled定时任务,同一时间段的定时任务只会执行一个,其余的会被阻塞,@Scheduled注解定时任务并发执行解决办法,即多线程运行定时任务
原文:https://blog.csdn.net/qq_35937303/article/details/88851064 现有两个定时任务 @Component("aa") pu ...
- Spring注解@Scheduled定时任务
一.首先配置applicationContext-task.xml (1)添加 xmlns:task="http://www.springframework.org/schema/task& ...
- spring注解scheduled实现定时任务
只想说,spring注解scheduled实现定时任务使用真的非常简单. 一.配置spring.xml文件 1.在beans加入xmlns:task="http://www.springfr ...
- Spring 的@Scheduled注解实现定时任务运行和调度
Spring 的@Scheduled注解实现定时任务运行和调度 首先要配置我们的spring.xml --- 即spring的主配置文件(有的项目中叫做applicationContext.xm ...
- Spring @Scheduled定时任务动态修改cron参数
在定时任务类上增加@EnableScheduling注解,并实现SchedulingConfigurer接口.(注意低版本无效) 设置一个静态变量cron,用于存放任务执行周期参数. 另辟一线程,用于 ...
- Spring的@Scheduled任务调度
一. 定时任务实现方式 定时任务实现方式: Java自带的java.util.Timer类,这个类允许你调度一个java.util.TimerTask任务.使用这种方式可以让你的程序按照某一个频度执行 ...
- Spring Boot (29) 定时任务
使用场景:数据定时增量同步,定时发送邮件,爬虫定时抓取 定时任务概述 定时任务:顾名思义就是在特定/指 定的时间进行工作,比如我们的手机闹钟,他就是一种定时的任务. 实现方式: 1.Timer:JDK ...
- Spring Boot 实现定时任务的 4 种方式
作者:Wan QingHua wanqhblog.top/2018/02/01/SpringBootTaskSchedule/ 定时任务实现的几种方式: Timer:这是java自带的java.uti ...
随机推荐
- C#虚函数和接口的区别
接口只能声明不能实现,虚函数可以. 接口:对外提供可以访问的函数叫接口.虚函数不需要被强制重写,其本身含有实现部分. 抽象类:指派了派生类必须实现的函数(纯虚函数),不然编译不通过. 虚函数的限制: ...
- WIN7 + IIS7 Service Unavailable HTTP Error 503. The service is unavailable.
在win7上开启IIS功能,进行网站发布. 但是开启IIS之后,打开默认网站都打不开,显示 Service Unavailable HTTP Error 503. The service is una ...
- DD_belatedPNG.js解决透明PNG图片背景灰色问题
<!--[]> <script type="text/javascript" src="http://www.phpddt.com/usr/themes ...
- C#中精确计时的一点收获 【转】
C#中精确计时的一点收获 [转] 以下所有代码运行环境:Windows 2003, Intel(R) Core(TM) 2 Duo CPU E8400 @ 3.00GHz 2.99GHz,2.96G ...
- js自适应屏幕高度
//自适应屏幕高度 $(window).resize(function() { hightChange(); }); function hightChange(){ ; $();// iframe i ...
- 大熊君学习html5系列之------requestAnimationFrame(实现动画的另一种方案)
一,开篇分析 Hi,大家好!大熊君又和大家见面了,(*^__^*) 嘻嘻……,这系列文章主要是学习Html5相关的知识点,以学习API知识点为入口,由浅入深的引入实例, 让大家一步一步的体会" ...
- fzoj1314 You are my brother
题目描述 Little A gets to know a new friend, Little B, recently. One day, they realize that they are fam ...
- UI第九节——UIStepper
- (void)viewDidLoad { [super viewDidLoad]; // 实例化UIStepper,大小是固定的 UIStepper *stepper = ...
- Android中的动画机制
1 逐帧动画 逐帧动画 就是一系列的图片按照一定的顺序展示的过程. 逐帧动画很简单, 只需要在drawable中或者anim中定义一个Animation-list 其中包含多个it ...
- js倒计时代码 适合于促销-倒计时代码
<div class="tiem_price clearfix fonts" style="margin-top:15px;"> <div c ...