Spring与多线程
前言背景
在做新项目,作为中间件的项目,主要做数据服务。这次想把项目做的简洁一些,之前用的什么ActiveMq等中间件产品,这次全部不用,能自己实现就自己实现。自己用BlockingQueue阻塞队列,按照自己的数据量,1G内存也能存上两千多万数据。设计上,需要一个线程去阻塞队列中拿数据,必须是系统启动的时候就去取。没有则阻塞,直到有数据来。
首先一个问题是,在spring项目中,自定义的New对象和线程,是不受spring管理的。所以在以前的处理中,经常是写一个单例,获取ApplicationContext,这种方式是可行的。但是在用注解的时候,使用这种方式,看上去会比较丑陋。所以,我们还是希望,在使用线程的时候,可以 像以前那样,可以自动的注入我们需要的bean。
开始动手
还是用实际的项目来举个栗子。
作为数据服务,入口是一个webservices的接口,这里因为历史原因,还是采用soap方式。
入口如下:
@WebMethod
public FeedResult send(NocPacket nocPacket) {
logger.info("Receive data");
QueueManager.getInstance().put(nocPacket,Const.nocQueue);
return "successful";
}
这里采用生产者和消费者的模式,其中的Const.nocQueue,是我们的BlockingQueue,作为数据缓冲区。
既然如此,还应该有一个消费者。
之前说过,我们要在系统启动的时候,就去queue中取我们的数据,有则拿出来,作为业务处理,没有则阻塞,等待数据到来。同时,拿到数据后,将这些数据入库。
这里需要两个类,一个是随系统一起启动的,暂且叫守护程序吧。另一个是做主业务的。
守护程序代码:
/**
* Created by Wl on 15-6-17.
* 业务消费者
*/
@Component
public class Business {
private Logger logger = Logger.getLogger(Business.class);
@Autowired
private FlowDataService<FlowData> flowDataService;
public void doBusi() {
logger.info("业务线程开始");
ExecutorService executor = Executors.newCachedThreadPool();
BusiTask task = new BusiTask(Const.nocQueue,flowDataService);
executor.submit(task);
FlowData data = flowDataService.queryById(1);
logger.info("Get Data :"+data.getPlateNo());
}
}
处理业务的类:
/**
* Created by Wl on 15-6-17.
* 业务处理主方法
*/
public class BusiTask implements Callable<BlockingQueue<NocPacket>> {
private Logger logger = Logger.getLogger(BusiTask.class);
private BlockingQueue<NocPacket> queue;
private FlowDataService<FlowData> flowDataService;
public BusiTask(BlockingQueue<NocPacket> queue,FlowDataService<FlowData> flowDataService) {
this.queue = queue;
this.flowDataService = flowDataService;
}
public BlockingQueue<NocPacket> call() throws Exception {
NocPacket nocPacket = queue.take();
logger.info("Data:"+nocPacket.getGWName());
Payload sc = NocUtil.getPayload(nocPacket);
FlowData data = new FlowData();
flowDataService.add(data);
logger.info("成功插入数据");
return null;
}
}
此处,守护程序是随系统一起启动的,这一点可以用spring配置。这个守护程序不能有特殊性,它不能是我们自建的一个线程,也不能new一个方法,再去调用doBusi,因为这样就不受spring管理了。它的第一个目的是拿到注入的service。
这两个类,采用Future和Callable的方式进行异步线程处理的。如果直接去处理BusiTask中的任务,就会阻塞到queue的take上。同时,通过守护程序,BusiTask也可以拿到services,进行入库等操作。
结尾
spring是可以进行多线程开发的,目前没使用过,以后有时间好好研究下。
Spring与多线程的更多相关文章
- spring mvc 多线程并发
ThreadLocal为解决多线程程序的并发问题提供了一种新的思路.使用这个工具类可以很简洁地编写出优美的多线程程序. http://www.xuebuyuan.com/1628190.html 我们 ...
- 关于Spring在多线程下的个人疑问
在Web开发中,不可避免的是需要遇到并发操作的,并发操作就有可能会引发我们的多线程安全问题.比如说,我们多线程下访问同一个变量并且有一个线程做出修改那么就会使得我们另外的线程在不知情的情况下被修改自己 ...
- 使用spring的多线程机制
多线程并发处理起来通常比較麻烦,假设你使用spring容器来管理业务bean,事情就好办了多了.spring封装了java的多线程的实现,你仅仅须要关注于并发事物的流程以及一些并发负载量等特性. 详细 ...
- Spring单例模式多线程安全问题-有状态的Bean
Spring单例与线程安全小结 一.Spring单例模式与线程安全 Spring框架里的bean,或者说组件,获取实例的时候都是默认的单例模式,这是在多线程开发的时候要尤其注意的地方. 单例模式的意思 ...
- Spring 在多线程中,bean的注入问题
最近碰到了一个问题,使用SSM框架,在Service层需要另开一个线程,这个线程专门用来做一些操作,并将结果写入数据库中.但是在线程中使用@Resource或者@Autowired注入全部为NULL, ...
- Spring boot多线程
1.配置线程配置类 package test; import java.util.concurrent.Executor; import org.springframework.aop.interce ...
- Spring单实例、多线程安全、事务解析
原文:http://blog.csdn.net/c289054531/article/details/9196053 引言: 在使用Spring时,很多人可能对Spring中为什么DAO和Se ...
- spring多线程与定时任务
本篇主要描述一下spring的多线程的使用与定时任务的使用. 1.spring多线程任务的使用 spring通过任务执行器TaskExecutor来实现多线程与并发编程.通常使用ThreadPoolT ...
- spring quartz使用多线程并发“陷阱”
定义一个job:ranJob,设置每秒执行一次,设置不允许覆盖并发执行 <bean id="rankJob" class="com.chinacache.www.l ...
随机推荐
- vim删除单词
参考资料: https://blog.csdn.net/grey_csdn/article/details/72355735 混迹于Windows.Linux以及Mac,选择加强自己的VIM水平应该不 ...
- MySQL单行注释和多行释
单行注释:# 或者 -- 多行注释:/* ... */ 使用 # 时,# 和注释的内容之间可以没有空格 使用 -- 时,-- 和注释内容之间必须有空格
- Netty 源码 Channel(一)概述
Netty 源码 Channel(一)概述 Netty 系列目录(https://www.cnblogs.com/binarylei/p/10117436.html) Channel 为 Netty ...
- Python 之异常处理机制
python在程序运行出现错误时时有相应的反应机制 ,我们可以针对不同的错误做出不同的响应 list1 = ['a','b','c'] print(list1[4]) #>>>Ind ...
- spring Springmvc mybatis maven整合
一.准备工作 1. 首先创建一个表: CREATE TABLE `t_user` ( `USER_ID` int(11) NOT NULL AUTO_INCREMENT, `USER_NAME` ch ...
- NServiceBus消息重播
https://docs.particular.net/tutorials/message-replay/ 链接:https://pan.baidu.com/s/1KdWvpfZYZ2wUivkt3B ...
- IPV6修复工具
https://www.cnblogs.com/ysugyl/p/9000940.html
- mybatis 一次执行多条语句
现在的一些互联网应用 为了提高性能,现在一般比较少的使用外键.不是不用,只是在创建数据库不标明外键关系,用程序去维护. 为了维护数据一致性,我们需要手动完成相关数据的删除 比如用户和用户的关注 当用户 ...
- Linux学习笔记:JDK安装
系统为CentOS 7,安装Oracle jdk1.8 卸载系统自带的Openjdk(若无可跳过这一步,可以通过 java -version 查看),步骤是:查找Openjdk,卸载Openjdk r ...
- java中排序函数sort()使用,Arrays.sort()和Collections.sort()
Java中常用的数组或集合排序的方法有两个,一个是java.util.Arrays中的静态方法Arrays.sort(),还有一个是java.util.Collections中的静态方法的Collec ...