一、前言

在我们日常的开发中,经常用到数据同步的更新,这时我们采用的是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(定时任务)和多线程的更多相关文章

  1. Spring Boot Scheduled定时任务特性

    SpringBoot中的Scheduled定时任务是Spring Boot中非常常用的特性,用来执行一些比如日切或者日终对账这种定时任务 下面说说使用时要注意的Scheduled的几个特性 Sched ...

  2. spring的@Scheduled定时任务,同一时间段的定时任务只会执行一个,其余的会被阻塞,@Scheduled注解定时任务并发执行解决办法,即多线程运行定时任务

    原文:https://blog.csdn.net/qq_35937303/article/details/88851064 现有两个定时任务 @Component("aa") pu ...

  3. Spring注解@Scheduled定时任务

    一.首先配置applicationContext-task.xml (1)添加 xmlns:task="http://www.springframework.org/schema/task& ...

  4. spring注解scheduled实现定时任务

    只想说,spring注解scheduled实现定时任务使用真的非常简单. 一.配置spring.xml文件 1.在beans加入xmlns:task="http://www.springfr ...

  5. Spring 的@Scheduled注解实现定时任务运行和调度

    Spring 的@Scheduled注解实现定时任务运行和调度 首先要配置我们的spring.xml   ---  即spring的主配置文件(有的项目中叫做applicationContext.xm ...

  6. Spring @Scheduled定时任务动态修改cron参数

    在定时任务类上增加@EnableScheduling注解,并实现SchedulingConfigurer接口.(注意低版本无效) 设置一个静态变量cron,用于存放任务执行周期参数. 另辟一线程,用于 ...

  7. Spring的@Scheduled任务调度

    一. 定时任务实现方式 定时任务实现方式: Java自带的java.util.Timer类,这个类允许你调度一个java.util.TimerTask任务.使用这种方式可以让你的程序按照某一个频度执行 ...

  8. Spring Boot (29) 定时任务

    使用场景:数据定时增量同步,定时发送邮件,爬虫定时抓取 定时任务概述 定时任务:顾名思义就是在特定/指 定的时间进行工作,比如我们的手机闹钟,他就是一种定时的任务. 实现方式: 1.Timer:JDK ...

  9. Spring Boot 实现定时任务的 4 种方式

    作者:Wan QingHua wanqhblog.top/2018/02/01/SpringBootTaskSchedule/ 定时任务实现的几种方式: Timer:这是java自带的java.uti ...

随机推荐

  1. cURL函数

    PHP的cURL函数是通过libcurl库与服务器使用各种类型的协议进行连接和通信的,curl目前支持HTTP GET .HTTP POST .HTTPS认证.FTP上传.HTTP基于表单的上传.co ...

  2. 快排 快速排序 qsort quicksort C语言

    现在网上搜到的快排和我以前打的不太一样,感觉有点复杂,我用的快排是FreePascal里/demo/text/qsort.pp的风格,感觉特别简洁. #include<stdio.h> # ...

  3. [Git] Git基础

    远程仓库 查看远程仓库: git remote -v 添加远程仓库: git remote add <repoName> <url> 拉取远程仓库数据: git fetch & ...

  4. HTTP请求报文格式

    HTTP报文是面向文本的,报文中的每一个字段都是一些ASCII码串,各个字段的长度是不确定的.HTTP有两类报文:请求报文和响应报文. 请求报文 一个HTTP请求报文由请求行(request line ...

  5. 如何查看、修改Linux的系统时间

    如题: 如何修改Linux的系统时间? date -s 05/27/2011 date -s 10:24:00 clock -w 就这三条命令就OK了! 查看/修改Linux时区和时间 一.时区 1. ...

  6. NOIp2014 解题报告

    有史以来第一届面向社会征题的NOIp结束了.最开始以为面向社会征题会很难,但是这是我参加的最水的一次NOIp了. 由于停了两月的课,所以现在正在补文化科目就没时间打代码了.所以所有的题目就均不给出代码 ...

  7. Mac键盘图标与对应快捷按键标志汇总

    Mac键盘图标与对应快捷按键 ⌘--Command () win键 ⌃ --Control ctrl键 ⌥--Option (alt) ⇧--Shift ⇪--Caps Lock fn--功能键就是 ...

  8. JQuery 自动触发事件

    JQuery 常用模拟 有时候,需要通过模拟用户操作,来达到单击的效果.例如在用户进入页面后,就触发click事件,而不需要用户去主动单击. 在JQuery中,可以使用trigger()方法完成模拟操 ...

  9. NEFU 561 方块计算

    题目链接 简单搜索题 #include <cstdio> #include <iostream> #include <cstring> using namespac ...

  10. jquery 控件赋值

    input 文本框赋值$("#id").attr("赋值"); input 文本框清空$("#id").attr("") ...