- 浏览: 2182499 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (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 1922@ConfigurationProperties注解的作用 ... -
如何在Spring Boot项目使用参数校验
2016-11-02 16:30 6553开发web项目有时候我们需要对controller层传过来的参 ... -
使用SpringBoot1.4.0的一个坑
2016-08-16 10:08 7348时隔半年,再次使用Spring Boot快速搭建微服务,半 ... -
如何在Spring中注入ElasticSearch实例
2016-04-06 18:44 6302在企业级项目开发中,大多数公司都会集成Spring来简化开发 ... -
IntelliJ IDEA中使用svn遇到的小问题
2015-06-04 20:20 3481今天在用新装的IDEA 14. ... -
Spring Boot开发之弄月吟风 (三)
2015-04-27 21:11 8505今天来看下,如何在Spring Boot中使用热加载和集成V ... -
Spring Boot开发之流水无情(二)
2015-04-26 19:45 11772上篇散仙写了一个很 ... -
Spring Boot开发之明月千城(一)
2015-04-24 01:27 16608最近数据分析的项目也即将告一段落了,中间也积累了很多知识 ... -
记一次log4j日志文件小事故
2015-01-30 21:31 2502最近散仙在做公司的一个跟搜索有关的数据分析(Pig+Hadoo ... -
Struts2+Hibernate+Spring之3大框架集成小例子
2014-03-16 23:10 3622SSH框架集成,可以说是J ... -
了解HTTP协议
2014-02-23 11:08 810http协议全称超文本传 ... -
Spring MVC+MyBatics+Spring集成小例子
2014-01-12 15:56 3161散仙,在前面的博客中写过一篇,Spirng MVC+Hiber ... -
Spring项目的几种乱码问题解决思路
2014-01-12 14:33 1689与Spring结合做Web项目时,常常会出现乱码情况,这时候, ... -
配置Mybatics的XML文件的自动提示功能
2014-01-12 14:03 3345配置Mybatics的mapper文件的自动提示功能, M ... -
Spring MVC+Hibernate+Spring集成小例子
2014-01-08 20:30 4530上次,散仙给了一个关于Sping MVC注解简单的小例子,那么 ... -
Spring MVC+SimpleJdbcDaoSupport增删改查小例子
2014-01-03 17:38 2417散仙,上次给的例子是基于Spring MVC+JDBC的方式做 ... -
基于Spirng MVC注解入门
2014-01-01 23:21 1285spring2.5引入注解式处理器支持,通过@Controll ... -
Spring+Spring MVC+JDBC增删改查小例子
2014-01-01 21:52 3759此篇文章,也是作为入门时的一个小练习例子,使用的是JDBC完成 ... -
Spring MVC入门小例子
2014-01-01 21:36 3265入门Spring MVC也有一段时间了,今天写篇文章总结一下 ... -
JSP下载中文名乱码问题
2013-12-30 19:02 1273上传下载功能,几乎是 ...
相关推荐
其内部可能包括了数据源配置、路由策略、切换逻辑等组件,通过Spring Boot的自动配置能力,使得开发者可以方便地在项目中集成和使用。 使用这个启动器,开发者可以自定义数据源的配置,例如设置数据源的类型(如...
在 Spring Boot 项目中,使用多线程处理任务是一种常见的需求,尤其是在需要并发处理多个任务的情况下。那么,如何使用多线程处理任务方法呢?下面我们将详细介绍 Spring Boot 中多线程处理任务方法的实现。 首先,...
Disruptor的核心思想是利用内存局部性原理,减少缓存失效,以及通过预先分配内存空间和避免锁竞争,提高多线程环境下的数据交换速度。 Spring Boot Starter Disruptor启动器为开发者提供了一种简洁的方式来引入...
在 Spring Boot 项目中,使用多线程处理任务是非常重要的,特别是在监控项目中,每个被监控的业务都需要单独运行在一个线程中,具有自己的配置参数。那么,如何在 Spring Boot 项目中使用多线程处理任务呢? 首先,...
在Spring Boot应用中,多线程的使用是一个关键特性,特别是在处理高并发或者需要执行耗时操作时。本文将深入探讨Spring Boot如何实现多线程,并结合提供的`spring-boot-multithreading.zip`压缩包中的示例进行讲解。...
在Spring Boot项目中,多数据源配置是一项关键的技术,它允许我们连接并操作多个数据库,这对于数据隔离、读写分离或者分布式系统来说是至关重要的。本篇将详细讲解如何在基于Maven构建的Spring Boot应用中实现多...
SLF4J(Simple Logging Facade for Java)是Java日志框架的一个抽象层,它提供了一个通用的日志API,允许...通过这个项目,你可以学习如何在实际应用中配置和使用SLF4J,以及如何利用Spring Boot的特性优化日志处理。
在这个名为 "spring-boot-cache.rar" 的压缩包中,我们很可能是找到了一个基于 Spring Boot 的小型项目,它展示了如何在 Spring Boot 应用中集成和使用缓存功能。下面我们将详细探讨 Spring Boot 缓存的相关知识点。...
在Spring Boot应用中,事务管理和多线程是两个非常关键的特性,特别是在处理复杂的业务逻辑时。本示例将深入探讨如何使用注解来实现事务控制以及如何在Spring Boot中运用多线程。 首先,让我们关注"注解事务"。在...
4. **配置多数据源**: 在Spring Boot中,可以通过配置不同的`@Configuration`类来设置多个数据源。每个数据源可以有自己的`DataSourceProperties`,并通过`@Bean`注解创建对应的`DataSource`实例。 5. **切换数据源...
在“spring-boot-2.6.6.zip”这个压缩包中,我们获得了 Spring Boot 的具体版本 2.6.6,这是一次重要的更新,包含了多项改进和新特性。 Spring Boot 2.6.6 版本的知识点主要包括以下几个方面: 1. **自动配置**:...
在配置事务时,Spring Boot也能自动处理多数据源的事务管理。 8. **扩展性** `dynamic-datasource-spring-boot-starter`支持自定义数据源策略,允许开发者根据项目需求实现特定的数据源选择逻辑。 9. **最佳实践*...
在 springboot-hb 或 springboot-hibernate 示例中,SessionFactory 可能是通过 Spring Boot 的自动配置得到的,用于处理数据库会话的创建和关闭。 这个压缩包为初学者和经验丰富的开发者提供了很好的学习资源,...
多线程:Java中的多线程编程是面试中经常考查的部分,涉及到线程的基本概念、线程安全、线程同步等。线程的基本状态包括新建、就绪、运行、阻塞和死亡。Java提供了synchronized关键字来实现线程的同步,它依赖于JVM...
本项目"spring-boot-mybatis-annotation-mulidatasource"着重于利用Spring Boot和MyBatis注解实现多数据源连接,这在处理多个数据库或者分库分表的场景中非常实用。 首先,Spring Boot提供了自动配置功能,使得我们...
5. **新并发工具**:如`ForkJoinPool`和`CompletableFuture`,增强了多线程编程的能力。 【Spring Boot 2.7.18】是Spring框架的一个子项目,致力于简化Spring应用的初始搭建以及开发过程。其特点包括: 1. **自动...
此外,考虑使用异步处理和多线程以提高文件操作性能。 在"spring-boot-minio-master"这个项目中,你可能会看到上述各个部分的具体实现,包括配置文件、服务类、控制器类等。通过学习这个示例,你可以理解Spring ...
在Spring Boot应用中,使用JDBC处理数据是常见的实践,特别是在需要管理多个数据源的场景下。本示例"spring-boot-jdbc多数据源的demo"将帮助我们理解如何在Spring Boot环境中配置和操作多个数据库。多数据源的实现...
6. **线程管理**:如果需要并发处理多个TCP连接,可以使用ExecutorService来管理线程池。 7. **集成测试**:在描述中提到“已测试”,这表明可能有测试用例或测试类来验证TCP客户端的功能,如`@SpringBootTest`和`@...
基于Spring-Boot的排队功能Demo,通过线程同步实现简单的排队功能,运用了多线程同步技术,可通过PostMan进行接口的并发访问模拟,在调用接口时需要在Head里加入openId参数作为客户访问的唯一标识,房间状态由定时器...