并发–执行程序和Spring集成

基于线程池/执行器的实现

比原始线程版本更好的方法是基于线程池的线程池,其中基于运行任务的系统定义了适当的线程池大小– CPU数量/(任务的1-Blocking Coefficient)。 Venkat Subramaniams书中有更多详细信息:

首先,在给定“报告部件请求”的情况下,我定义了一个自定义任务来生成“报告部件”,将其实现为Callable :

public class ReportPartRequestCallable implements Callable<ReportPart> {private final ReportRequestPart reportRequestPart;private final ReportPartGenerator reportPartGenerator;public ReportPartRequestCallable(ReportRequestPart reportRequestPart, ReportPartGenerator reportPartGenerator) {this.reportRequestPart = reportRequestPart;this.reportPartGenerator = reportPartGenerator;}@Overridepublic ReportPart call() {return this.reportPartGenerator.generateReportPart(reportRequestPart);} 
}
public class ExecutorsBasedReportGenerator implements ReportGenerator {private static final Logger logger = LoggerFactory.getLogger(ExecutorsBasedReportGenerator.class);private ReportPartGenerator reportPartGenerator;private ExecutorService executors = Executors.newFixedThreadPool(10);@Overridepublic Report generateReport(ReportRequest reportRequest) {List<Callable<ReportPart>> tasks = new ArrayList<Callable<ReportPart>>();List<ReportRequestPart> reportRequestParts = reportRequest.getRequestParts();for (ReportRequestPart reportRequestPart : reportRequestParts) {tasks.add(new ReportPartRequestCallable(reportRequestPart, reportPartGenerator));}List<Future<ReportPart>> responseForReportPartList;List<ReportPart> reportParts = new ArrayList<ReportPart>();try {responseForReportPartList = executors.invokeAll(tasks);for (Future<ReportPart> reportPartFuture : responseForReportPartList) {reportParts.add(reportPartFuture.get());}} catch (Exception e) {logger.error(e.getMessage(), e);throw new RuntimeException(e);}return new Report(reportParts);}......
}

在这里,使用Executors.newFixedThreadPool(10)调用创建线程池,线程池的大小为10,为每个报告请求部分生成一个可调用任务,并使用ExecutorService抽象将其移交给线程池

responseForReportPartList = executors.invokeAll(tasks);

此调用返回一个期货列表,该列表支持get()方法,这是对响应可用的阻塞调用。

与原始线程版本相比,这显然是一个更好的实现,线程数量在负载下被限制为可管理的数量。

基于Spring集成的实现

我个人最喜欢的方法是使用Spring Integration ,原因是使用Spring Integration时 ,我专注于完成不同任务的组件,并留给Spring Integration使用基于xml或基于注释的配置将流程连接在一起。 在这里,我将使用基于XML的配置:

在我的案例中,这些组件是:
1.给出报告部分的请求,生成报告部分的组件,我之前已经显示过 。
2.用于将报告请求拆分为报告请求部分的组件:

public class DefaultReportRequestSplitter implements ReportRequestSplitter{@Overridepublic List<ReportRequestPart> split(ReportRequest reportRequest) {return reportRequest.getRequestParts();}
}

3.用于将报告部分组装/汇总为整个报告的组件:

public class DefaultReportAggregator implements ReportAggregator{@Overridepublic Report aggregate(List<ReportPart> reportParts) {return new Report(reportParts);}}

这就是Spring Integration所需的所有Java代码,其余的都是接线–在这里,我使用了Spring Integration配置文件:

<?xml version='1.0' encoding='UTF-8'?>
<beans ....<int:channel id='report.partsChannel'/><int:channel id='report.reportChannel'/><int:channel id='report.partReportChannel'><int:queue capacity='50'/></int:channel>  <int:channel id='report.joinPartsChannel'/><int:splitter id='splitter' ref='reportsPartSplitter' method='split' input-channel='report.partsChannel' output-channel='report.partReportChannel'/><task:executor id='reportPartGeneratorExecutor' pool-size='10' queue-capacity='50' /><int:service-activator id='reportsPartServiceActivator'  ref='reportPartReportGenerator' method='generateReportPart' input-channel='report.partReportChannel' output-channel='report.joinPartsChannel'><int:poller task-executor='reportPartGeneratorExecutor' fixed-delay='500'></int:poller></int:service-activator><int:aggregator ref='reportAggregator' method='aggregate' input-channel='report.joinPartsChannel' output-channel='report.reportChannel' ></int:aggregator> <int:gateway id='reportGeneratorGateway' service-interface='org.bk.sisample.springintegration.ReportGeneratorGateway' default-request-channel='report.partsChannel' default-reply-channel='report.reportChannel'/><bean name='reportsPartSplitter' class='org.bk.sisample.springintegration.processors.DefaultReportRequestSplitter'></bean><bean name='reportPartReportGenerator' class='org.bk.sisample.processors.DummyReportPartGenerator'/><bean name='reportAggregator' class='org.bk.sisample.springintegration.processors.DefaultReportAggregator'/><bean name='reportGenerator' class='org.bk.sisample.springintegration.SpringIntegrationBasedReportGenerator'/></beans>

Spring Source Tool Suite提供了一种可视化此文件的好方法:

这完全符合我对用户流的原始看法:

在代码的Spring Integration版本中,我定义了不同的组件来处理流程的不同部分:
1.将报告请求转换为报告请求部分的拆分器:

<int:splitter id='splitter' ref='reportsPartSplitter' method='split' input-channel='report.partsChannel' output-channel='report.partReportChannel'/>

2.服务激活器组件,用于根据报告部件请求生成报告部件:

<int:service-activator id='reportsPartServiceActivator'  ref='reportPartReportGenerator' method='generateReportPart' input-channel='report.partReportChannel' output-channel='report.joinPartsChannel'><int:poller task-executor='reportPartGeneratorExecutor' fixed-delay='500'></int:poller></int:service-activator>

3.聚合器,用于将报表部分重新加入报表,并且足够智能,可以适当地关联原始拆分报表请求,而无需任何显式编码:

<int:aggregator ref='reportAggregator' method='aggregate' input-channel='report.joinPartsChannel' output-channel='report.reportChannel' ></int:aggregator>

这段代码有趣的是,就像在基于执行者的示例中一样,使用xml文件,通过使用适当的通道将不同的组件连接在一起以及通过使用任务执行器 ,可以完全配置服务于每个组件的线程数。设置为执行程序属性的线程池大小。

在这段代码中,我定义了一个队列通道,其中报告请求部分进入其中:

<int:channel id='report.partReportChannel'><int:queue capacity='50'/></int:channel>

并由服务激活器组件使用任务执行器提供服务,该任务执行器的线程池大小为10,容量为50:

<task:executor id='reportPartGeneratorExecutor' pool-size='10' queue-capacity='50' /><int:service-activator id='reportsPartServiceActivator'  ref='reportPartReportGenerator' method='generateReportPart' input-channel='report.partReportChannel' output-channel='report.joinPartsChannel'><int:poller task-executor='reportPartGeneratorExecutor' fixed-delay='500'></int:poller></int:service-activator>

所有这些都通过配置!

该示例的完整代码库可在以下github位置获得: https : //github.com/bijukunjummen/si-sample

参考: 并发–来自JCG合作伙伴 Biju Kunjummen的“ 执行程序和Spring集成” ,位于all和其他博客上。


翻译自: https://www.javacodegeeks.com/2012/06/concurrency-executors-and-spring.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/372377.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

后面的参数_英特尔I系列CPU大家都知道,后面的参数你有没有了解过

嗨&#xff01;大家好&#xff0c;我是伟仔&#xff0c;今天主要是和大家聊下CPU。大多数人买笔记本或台式电脑对CPU的要求就知道I5或者I7之类的。像是I7一定比I5要好&#xff0c;I3很LOU这样的&#xff0c;当然这样子的观点是不正确的&#xff0c;今天我会告诉大家&#xff0c…

設置Linux保留物理內存並使用 (1)

在Linux系統中可以通過memblock來設置系統保留物理內存&#xff0c;防止這些內存被內存管理系統分配出去。 作者&#xff1a; 彭東林 郵箱&#xff1a; pengdonglin137163.com 平臺 硬件平臺&#xff1a; TQ2440 Linux版本&#xff1a;Linux 3.14.45 說明 1. 在tq2440上&#x…

移动端

http://www.w3cplus.com/mobile/lib-flexible-for-html5-layout.html 移动端手淘使用方案 移动端px自动转换rem插件 CSSREM Flexible 转载于:https://www.cnblogs.com/yuruiweb/p/6723580.html

OutOfMemoryError:Java堆空间–分析和解决方法

java.lang.OutOfMemoryError&#xff1a;Java堆问题是在支持或开发复杂的Java EE应用程序时可能会遇到的最复杂的问题之一。 这篇简短的文章将为您提供此JVM HotSpot OutOfMemoryError错误消息的描述&#xff0c;以及在解决该问题之前应如何解决此问题。 有关如何确定要处理的O…

函数伪代码_Excel常用函数

欢迎大家在此收看任我行office教程系列&#xff0c;这一期我来为大家讲什么内容呢&#xff0c;那就是几个office的几个常用函数了&#xff0c;如果您不会这些函数和函数嵌套那么您的Excel电子表格也就别玩了哈&#xff0c;那么他们分别是什么函数呢。咱们现在隆重有请这几位函数…

阻止Ajax多次提交

1、Ajax的abort() xhr $.ajax({})if (xhr){xhr.abort(); } 2、通过在Ajax的beforeSend()方法以及complete()方法添加删除类&#xff0c;对类进行判断&#xff0c;对于两者来回切换的时候&#xff0c;对类的设置不好进行操作上的时候&#xff0c;可以通过使用一个input框&#…

POJ3675 Telescope 圆和多边形的交

POJ3675 用三角剖分可以轻松搞定&#xff0c;数据也小 随便AC。 #include<iostream> #include<stdio.h> #include<stdlib.h> #include<string.h> #include<math.h> #include<algorithm> #include<queue> #include<vector> usi…

windows搭建python开发环境方法_04 Windows下搭建 Python 开发环境 - Python 入门教程

前面两个小节中我们已经学习了在 MacOS 和 Ubuntu 中安装 Python 的开发环境。当然&#xff0c;作为用户基数最多的 Windows 操作系统&#xff0c;我们当然不会忘记&#xff0c;这节课我们就来学习下如何在 Windows 下搭建 Python 的开发环境。1. 下载 Python1.1 Python 2 与 P…

消除view旋转后边缘有锯齿的情况

view的layer中有个属性叫 allowsEdgeAntialiasing&#xff1b; 在形变后有边缘有锯齿的话 可以 view.layer.allowsEdgeAntialiasing YES; 消除锯齿 如果直接在*-Info.plist配置 Renders with edge antialiasing YES 会导致UIAlertView显示有问题。转载于:https://www.cnblogs…

Google AppEngine:任务队列API

任务队列 com.google.appengine.api.taskqueue 使用任务队列&#xff0c;用户可以发起一个请求&#xff0c;以使应用程序执行此请求之外的工作。 它们是进行后台工作的强大工具。 此外&#xff0c;您可以将工作组织成小的离散单元&#xff08;任务&#xff09;。 然后&#xf…

打印5列五颗星_55组“数学顺口溜” 大九九乘法口诀表!孩子想学好数学必须背熟...

小学数学需要记住的知识点还是比较多的&#xff0c;看到这些知识点&#xff0c;很多孩子都觉得枯燥&#xff0c;不愿意用心去记。今天&#xff0c;我们给孩子们汇总了55组“数学顺口溜”和大九九乘法口诀&#xff0c;让孩子们在轻松有趣的氛围中学到知识&#xff01;55组“顺口…

C++学习48 对ASCII文件的读写操作

如果文件的每一个字节中均以ASCII代码形式存放数据,即一个字节存放一个字符,这个文件就是ASCII文件(或称字符文件)。程序可以从ASCII文件中读入若干个字符,也可以向它输出一些字符。 对ASCII文件的读写操作可以用以下两种方法&#xff1a;1) 用流插入运算符“<<”和流提取…

文献综述写作之“结构内容”

综述&#xff1a; 又称文献综述&#xff0c;英文名为review。它是利用已发表的文献资料为原始素材撰写的&#xff0c;通过对已发表材料的组织、综合和评价&#xff0c;以及对当前研究进展的考察来澄清问题。在某种意义上&#xff0c;综述论文具有一定的指导性&#xff0c;包括以…

NetBeans 7.2 beta:更快,更有用

NetBeans 7.2的beta版本引起了极大的兴奋。 在本文中&#xff0c;我将简要介绍一下此版本令人兴奋的原因&#xff08;包括更好的性能&#xff0c;提供更多的提示以及集成FindBugs&#xff09;。 NetBeans 7.2 beta在典型的下载捆绑软件中可用&#xff0c;从较小的Java SE&#…

地铁闸门会夹伤人吗_家长们注意啦!又有孩子被地铁闸机夹翻

原标题&#xff1a;家长们注意啦&#xff01;又有孩子被地铁闸机夹翻现代快报讯(通讯员狄公宣记者顾元森)家长带着孩子通过地铁站闸机&#xff0c;这件事情看似简单&#xff0c;却隐藏着风险。近日&#xff0c;南京地铁又发生了一起儿童被闸机夹翻的事&#xff0c;所幸孩子并无…

WPF DevExpress 设置雷达图Radar样式

DevExpress中定义的ChartControl很不错&#xff0c;很多项目直接使用这种控件。 本节讲述雷达图的样式设置 <Grid><Grid.Resources><DataTemplate x:Key"LabelItemDataTemplate" DataType"dxc:SeriesLabelItem"><Border CornerRadius…

mxnet系列教程之1-第一个例子

第一个例子当然是mnist的例子 假设已经成功安装了mxnet 例子的代码如下&#xff1a; cd mxnet/example/image-classification python train_mnist.py这样就会运行下去 train_mnist.py的代码为 """ Train mnist, see more explanation at http://mxnet.io/tutori…

Apache Shiro第3部分–密码学

除了保护网页和管理访问权限外&#xff0c; Apache Shiro还执行基本的加密任务。 该框架能够&#xff1a; 加密和解密数据&#xff0c; 哈希数据&#xff0c; 生成随机数。 Shiro没有实现任何加密算法。 所有计算都委托给Java密码学扩展&#xff08;JCE&#xff09;API。 使…

mysql数据存在就更新_Mysql:如果数据存在则更新,不存在则插入

mysql语法支持如果数据存在则更新&#xff0c;不存在则插入&#xff0c;首先判断数据存在还是不存在的那个字段要设置成unique索引&#xff0c;例如表tb_addrbook如下&#xff1a;索引&#xff1a;语句1:不存在插入INSERT INTO tb_addrbook(num,name,mobile) VALUE(1001,小李,1…

Memcached, Redis, MongoDB区别

mongodb和memcached不是一个范畴内的东西。mongodb是文档型的非关系型数据库&#xff0c;其优势在于查询功能比较强大&#xff0c;能存储海量数据。mongodb和memcached不存在谁替换谁的问题。和memcached更为接近的是redis。它们都是内存型数据库&#xff0c;数据保存在内存中&…