- 浏览: 2147499 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (682)
- 软件思想 (7)
- Lucene(修真篇) (17)
- Lucene(仙界篇) (20)
- Lucene(神界篇) (11)
- Solr (48)
- Hadoop (77)
- Spark (38)
- Hbase (26)
- Hive (19)
- Pig (25)
- ELK (64)
- Zookeeper (12)
- JAVA (119)
- Linux (59)
- 多线程 (8)
- Nutch (5)
- JAVA EE (21)
- Oracle (7)
- Python (32)
- Xml (5)
- Gson (1)
- Cygwin (1)
- JavaScript (4)
- MySQL (9)
- Lucene/Solr(转) (5)
- 缓存 (2)
- Github/Git (1)
- 开源爬虫 (1)
- Hadoop运维 (7)
- shell命令 (9)
- 生活感悟 (42)
- shell编程 (23)
- Scala (11)
- MongoDB (3)
- docker (2)
- Nodejs (3)
- Neo4j (5)
- storm (3)
- opencv (1)
最新评论
-
qindongliang1922:
粟谷_sugu 写道不太理解“分词字段存储docvalue是没 ...
浅谈Lucene中的DocValues -
粟谷_sugu:
不太理解“分词字段存储docvalue是没有意义的”,这句话, ...
浅谈Lucene中的DocValues -
yin_bp:
高性能elasticsearch ORM开发库使用文档http ...
为什么说Elasticsearch搜索是近实时的? -
hackWang:
请问博主,有用solr做电商的搜索项目?
Solr中Group和Facet的用法 -
章司nana:
遇到的问题同楼上 为什么会返回null
Lucene4.3开发之第八步之渡劫初期(八)
[size=medium]看到这个标题,相信不少人会感到疑惑,回忆你们自己的场景会发现,在Spring的项目中很少有使用多线程处理任务的,没错,大多数时候我们都是使用Spring MVC开发的web项目,默认的Controller,Service,Dao组件的作用域都是单实例,无状态,然后被并发多线程调用,那么如果我想使用多线程处理任务,该如何做呢?
比如如下场景:
使用spring-boot开发一个监控的项目,每个被监控的业务(可能是一个数据库表或者是一个pid进程)都会单独运行在一个线程中,有自己配置的参数,总结起来就是:
(1)多实例(多个业务,每个业务相互隔离互不影响)
(2)有状态(每个业务,都有自己的配置参数)
如果是非spring-boot项目,实现起来可能会相对简单点,直接new多线程启动,然后传入不同的参数类即可,在spring的项目中,由于Bean对象是spring容器管理的,你直接new出来的对象是没法使用的,就算你能new成功,但是bean里面依赖的其他组件比如Dao,是没法初始化的,因为你饶过了spring,默认的spring初始化一个类时,其相关依赖的组件都会被初始化,但是自己new出来的类,是不具备这种功能的,所以我们需要通过spring来获取我们自己的线程类,那么如何通过spring获取类实例呢,需要定义如下的一个类来获取SpringContext上下文:
/** * Created by Administrator on 2016/8/18. * 设置Sping的上下文 */ @Component public class ApplicationContextProvider implements ApplicationContextAware { private static ApplicationContext context; private ApplicationContextProvider(){} @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { context = applicationContext; } public static <T> T getBean(String name,Class<T> aClass){ return context.getBean(name,aClass); } }
然后定义我们的自己的线程类,注意此类是原型作用域,不能是默认的单例:
@Component("mTask") @Scope("prototype") public class MoniotrTask extends Thread { final static Logger logger= LoggerFactory.getLogger(MoniotrTask.class); //参数封装 private Monitor monitor; public void setMonitor(Monitor monitor) { this.monitor = monitor; } @Resource(name = "greaterDaoImpl") private RuleDao greaterDaoImpl; @Override public void run() { logger.info("线程:"+Thread.currentThread().getName()+"运行中....."); } }
写个测试例子,测试下使用SpringContext获取Bean,查看是否是多实例:
/** * Created by Administrator on 2016/8/18. */ @RunWith(SpringJUnit4ClassRunner.class) @SpringBootTest(classes =ApplicationMain.class) public class SpingContextTest { @Test public void show()throws Exception{ MoniotrTask m1= ApplicationContextProvider.getBean("mTask", MoniotrTask.class); MoniotrTask m2=ApplicationContextProvider.getBean("mTask", MoniotrTask.class); MoniotrTask m3=ApplicationContextProvider.getBean("mTask", MoniotrTask.class); System.out.println(m1+" => "+m1.greaterDaoImpl); System.out.println(m2+" => "+m2.greaterDaoImpl); System.out.println(m3+" => "+m3.greaterDaoImpl); } }
运行结果如下:
[ INFO ] [2016-08-25 17:36:34] com.test.tools.SpingContextTest [57] - Started SpingContextTest in 2.902 seconds (JVM running for 4.196) 2016-08-25 17:36:34.842 INFO 8312 --- [ main] com.test.tools.SpingContextTest : Started SpingContextTest in 2.902 seconds (JVM running for 4.196) Thread[Thread-2,5,main] => com.xuele.bigdata.xalert.dao.rule.impl.GreaterDaoImpl@285f38f6 Thread[Thread-3,5,main] => com.xuele.bigdata.xalert.dao.rule.impl.GreaterDaoImpl@285f38f6 Thread[Thread-4,5,main] => com.xuele.bigdata.xalert.dao.rule.impl.GreaterDaoImpl@285f38f6
可以看到我们的监控类是多实例的,它里面的Dao是单实例的,这样以来我们就可以在spring中使用多线程处理我们的任务了。
如何启动我们的多线程任务类,可以专门定义一个组件类启动也可以在启动Spring的main方法中启动,下面看下,如何定义组件启动:
@Component public class StartTask { final static Logger logger= LoggerFactory.getLogger(StartTask.class); //定义在构造方法完毕后,执行这个初始化方法 @PostConstruct public void init(){ final List<Monitor> list = ParseRuleUtils.parseRules(); logger.info("监控任务的总Task数:{}",list.size()); for(int i=0;i<list.size();i++) { MoniotrTask moniotrTask= ApplicationContextProvider.getBean("mTask", MoniotrTask.class); moniotrTask.setMonitor(list.get(i)); moniotrTask.start(); logger.info("第{}个监控task: {}启动 !",(i+1),list.get(i).getName()); } } }
最后备忘下logback.xml,里面可以配置相对和绝对的日志文件路径:
<!-- Logback configuration. See http://logback.qos.ch/manual/index.html --> <configuration scan="true" scanPeriod="10 seconds"> <!-- Simple file output --> <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <!--<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">--> <!-- encoder defaults to ch.qos.logback.classic.encoder.PatternLayoutEncoder --> <encoder> <pattern> [ %-5level] [%date{yyyy-MM-dd HH:mm:ss}] %logger{96} [%line] - %msg%n </pattern> <charset>UTF-8</charset> <!-- 此处设置字符集 --> </encoder> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <!-- rollover daily 配置日志所生成的目录以及生成文件名的规则,默认是相对路径 --> <fileNamePattern>logs/xalert-%d{yyyy-MM-dd}.%i.log</fileNamePattern> <!--<property name="logDir" value="E:/testlog" />--> <!--绝对路径定义--> <!--<fileNamePattern>${logDir}/logs/xalert-%d{yyyy-MM-dd}.%i.log</fileNamePattern>--> <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> <!-- or whenever the file size reaches 64 MB --> <maxFileSize>64 MB</maxFileSize> </timeBasedFileNamingAndTriggeringPolicy> </rollingPolicy> <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> <level>DEBUG</level> </filter> <!-- Safely log to the same file from multiple JVMs. Degrades performance! --> <prudent>true</prudent> </appender> <!-- Console output --> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <!-- encoder defaults to ch.qos.logback.classic.encoder.PatternLayoutEncoder --> <encoder> <pattern> [ %-5level] [%date{yyyy-MM-dd HH:mm:ss}] %logger{96} [%line] - %msg%n </pattern> <charset>UTF-8</charset> <!-- 此处设置字符集 --> </encoder> <!-- Only log level WARN and above --> <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> <level>INFO</level> </filter> </appender> <!-- Enable FILE and STDOUT appenders for all log messages. By default, only log at level INFO and above. --> <root level="INFO"> <appender-ref ref="STDOUT" /> <appender-ref ref="FILE" /> </root> <!-- For loggers in the these namespaces, log at all levels. --> <logger name="pedestal" level="ALL" /> <logger name="hammock-cafe" level="ALL" /> <logger name="user" level="ALL" /> <include resource="org/springframework/boot/logging/logback/base.xml"/> <jmxConfigurator/> </configuration
有什么问题可以扫码关注微信公众号:我是攻城师(woshigcs),在后台留言咨询。
技术债不能欠,健康债更不能欠, 求道之路,与君同行。
评论
4 楼
qindongliang1922
2016-08-26
angelxdb 写道
这样做,把简单得倒复杂了,后面业务怎么处理,三套ApplicationContext,意味着后面三套逻辑。spring boot本来就是单利模块化得。
ApplicationContext是静态的,你说的3个指定是?
3 楼
angelxdb
2016-08-26
这样做,把简单得倒复杂了,后面业务怎么处理,三套ApplicationContext,意味着后面三套逻辑。spring boot本来就是单利模块化得。
2 楼
qindongliang1922
2016-08-26
white_crucifix 写道
准确来说不是和 spring-boot相关,而是应该和 spring 相关吧
对,spring-boot属于spring
1 楼
white_crucifix
2016-08-26
准确来说不是和 spring-boot相关,而是应该和 spring 相关吧
发表评论
-
在spring-boot中使用@ConfigurationProperties
2017-10-28 19:24 1889@ConfigurationProperties注解的作用 ... -
如何在Spring Boot项目使用参数校验
2016-11-02 16:30 6511开发web项目有时候我们需要对controller层传过来的参 ... -
使用SpringBoot1.4.0的一个坑
2016-08-16 10:08 7299时隔半年,再次使用Spring Boot快速搭建微服务,半 ... -
如何在Spring中注入ElasticSearch实例
2016-04-06 18:44 6240在企业级项目开发中,大多数公司都会集成Spring来简化开发 ... -
IntelliJ IDEA中使用svn遇到的小问题
2015-06-04 20:20 3366今天在用新装的IDEA 14. ... -
Spring Boot开发之弄月吟风 (三)
2015-04-27 21:11 8453今天来看下,如何在Spring Boot中使用热加载和集成V ... -
Spring Boot开发之流水无情(二)
2015-04-26 19:45 11693上篇散仙写了一个很 ... -
Spring Boot开发之明月千城(一)
2015-04-24 01:27 16554最近数据分析的项目也即将告一段落了,中间也积累了很多知识 ... -
记一次log4j日志文件小事故
2015-01-30 21:31 2459最近散仙在做公司的一个跟搜索有关的数据分析(Pig+Hadoo ... -
Struts2+Hibernate+Spring之3大框架集成小例子
2014-03-16 23:10 3572SSH框架集成,可以说是J ... -
了解HTTP协议
2014-02-23 11:08 755http协议全称超文本传 ... -
Spring MVC+MyBatics+Spring集成小例子
2014-01-12 15:56 3128散仙,在前面的博客中写过一篇,Spirng MVC+Hiber ... -
Spring项目的几种乱码问题解决思路
2014-01-12 14:33 1651与Spring结合做Web项目时,常常会出现乱码情况,这时候, ... -
配置Mybatics的XML文件的自动提示功能
2014-01-12 14:03 3300配置Mybatics的mapper文件的自动提示功能, M ... -
Spring MVC+Hibernate+Spring集成小例子
2014-01-08 20:30 4494上次,散仙给了一个关于Sping MVC注解简单的小例子,那么 ... -
Spring MVC+SimpleJdbcDaoSupport增删改查小例子
2014-01-03 17:38 2378散仙,上次给的例子是基于Spring MVC+JDBC的方式做 ... -
基于Spirng MVC注解入门
2014-01-01 23:21 1224spring2.5引入注解式处理器支持,通过@Controll ... -
Spring+Spring MVC+JDBC增删改查小例子
2014-01-01 21:52 3714此篇文章,也是作为入门时的一个小练习例子,使用的是JDBC完成 ... -
Spring MVC入门小例子
2014-01-01 21:36 3214入门Spring MVC也有一段时间了,今天写篇文章总结一下 ... -
JSP下载中文名乱码问题
2013-12-30 19:02 1238上传下载功能,几乎是 ...
相关推荐
主要介绍了Spring-Boot中如何使用多线程处理任务方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
本篇文章主要介绍了详解Spring-Boot中如何使用多线程处理任务,具有一定的参考价值,感兴趣的小伙伴们可以参考一下。
spring boot 多线程的简单例子
spring boot 纯注解方法事务控制回滚,注解+简单配置文件使用多线程demo
Java面试全方位复习攻略,详解集合框架,hashmap底层原理,多线程,消息队列,radis,spring-boot ,Spring-cloud技术,等等
多线程 计划任务 cron fixDelay fixRate 条件注解@Conditional 组合注解与元注解 @Enable*注解的工作原理 直接导入配置类 依据条件选择配置类 动态注册Bean 测试 Spring ...
Spring Boot Admin为Spring Boot应用程序提供了一个简单的管理界面。 特征: 显示名称/编号和版本号 显示健康状况 显示指标 设置日志级别 与JMX-Beans交互 查看线程转储 查看痕迹 有关更多信息,请参见: : 如何...
基于Spring-Boot的排队功能Demo,通过线程同步实现简单的排队功能,运用了多线程同步技术,可通过PostMan进行接口的并发访问模拟,在调用接口时需要在Head里加入openId参数作为客户访问的唯一标识,房间状态由定时器...
主要介绍了spring-boot 多线程并发定时任务的解决方案,需要的朋友可以参考下
springboot多线程范例,Spring Boot中使用多线程的方式有很多种,最简单的方式就是使用@Async注解来实现。
但这个不是绝对的,考虑到多线程的特性,可能有时候不会使用缓存超时控制@DataProvider注解支持配置超时,超时将引发中断异常(InterruptedException),伴随异常处理逻辑使用方法1.配置pom.xml < dependency>
多线程支持: Java内置了对多线程的支持,允许程序同时执行多个任务。这对于开发需要高并发性能的应用程序(如服务器端应用、网络应用等)非常重要。 自动内存管理(垃圾回收): Java具有自动内存管理机制,通过...
主要介绍了Spring Boot整合FTPClient线程池的实现示例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
主要给大家介绍了关于Spring Boot如何优雅的使用多线程的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用Spring Boot具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
主要介绍了Spring boot使用多线程过程步骤解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
spring boot 通过任务执行器 taskexecutor 来实现多线程和并发编程。下面这篇文章主要给大家介绍了关于spring boot中多线程开发的注意事项,文中通过示例代码介绍的非常详细,需要的朋友可以参考下
activemq消息队列整合SpringBoot
主要介绍了Spring Boot中使用AOP统一处理web层异常的相关资料,需要的朋友可以参考下
spring 多线程队列执行
主要介绍了Spring boot如何通过@Scheduled实现定时任务及多线程配置,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下