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 ...
随机推荐
- 创建NetWorkDataset---FileGDB篇
/// <summary> /// 创建NetWorkDataset /// </summary> /// <returns>INetworkDataset.< ...
- webpack入坑之旅
转自: http://guowenfh.github.io/2016/03/24/vue-webpack-01-base/ http://guowenfh.github.io/2016/03/25/v ...
- XMPP开发环境配置
首先配置XMPP开发环境配置需要的软件 先安装xampp-osx-1.8.3-5-installer.dmg 安装成功后launchpad里会多出一个XAMPP(其他),点开里面的manager-os ...
- git版本控制管理实践-3
git -m 和git -a -m(-am) . 的区别? usally two steps to commit files to respository: first, git add somefi ...
- PHP 表单
PHP 中的 $_GET 和 $_POST 变量用于检索表单中的信息,比如用户输入. 表单验证: 应该在任何可能的时候对用户输入进行验证(通过客户端脚本).浏览器验证速度更快,并且可以减轻服务器的负载 ...
- UVA2322
题目:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_pr ...
- rsa 签名 加密解密
A->B 签名 ==========================A方+A方的私钥 => B收到后 用A方的公钥 验证签名 ==========================A-> ...
- FileZillaFTP使用教程
FileZillaServer.exe服务启动和关闭程序 FileZilla Server Interface.exe 服务 管理程序 配置ftp服务器的用户名,密码,目录,目录读写权限 启动File ...
- C#夯实基础系列之const与readonly
一.const与readonly的争议 你一定写过const,也一定用过readonly,但说起两者的区别,并说出何时用const,何时用readonly,你是否能清晰有条理地说出个一二三 ...
- 难道这就是JavaScript中的"闭包"
其实对于JavaScript中的"闭包"还没真正理解,这次在实际Coding中似乎遇到了"闭包"的问题,仅此摘录,以待深究. 表现为jQuery的post方法回 ...