并发–执行程序和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…

移动端

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…

Google AppEngine:任务队列API

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

NetBeans 7.2 beta:更快,更有用

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

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…

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

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

【Hadoop】Hadoop MR 自定义分组 Partition机制

1、概念 2、Hadoop默认分组机制--所有的Key分到一个组&#xff0c;一个Reduce任务处理 3、代码示例 FlowBean package com.ares.hadoop.mr.flowgroup;import java.io.DataInput; import java.io.DataOutput; import java.io.IOException;import org.apache.hadoop.io.WritableC…

android学习笔记35——AnimationDrawable资源

AnimationDrawable资源 AnimationDrawable&#xff0c;代表一个动画。 android既支持传统的逐帧动画(类似于电影方式&#xff0c;一张图片一张图片的切换)&#xff0c;也支持通过平移、变换计算出来的补间动画、属性动画。 下面以补间动画为例&#xff0c;介绍如何定义Animatio…

mysql启动时执行sql server_常见 mysql 启动、运行.sql 文件错误处理

1、mysql 启动错误处理查看 log&#xff1a;Mac: /usr/local/var/mysql/lizhendeMacBook-Pro.local.err根据 log 针对性的进行调整&#xff0c;包治百病2、Mysql Incorrect datetime value问题描述&#xff1a;低版本的 mysql 中&#xff0c;数据库转储 sql 文件。导入到高版本…

带有谓词的Java中的函数样式-第2部分

在本文的第一部分中&#xff0c;我们介绍了谓词&#xff0c;这些谓词通过具有返回true或false的单个方法的简单接口&#xff0c;为Java等面向对象的语言带来了函数式编程的某些好处。 在第二部分和最后一部分中&#xff0c;我们将介绍一些更高级的概念&#xff0c;以使您的谓词…

原生JavaScript+CSS3实现移动端滑块效果

在做web页面时&#xff0c;无论PC端还是移动端&#xff0c;我们会遇到滑块这样的效果&#xff0c;可能我们往往会想着去网上找插件&#xff0c;其实这个效果非常的简单&#xff0c;插件代码的的代码往往过于臃肿&#xff0c;不如自己动手&#xff0c;自给自足。首先看一下效果图…

Activiti绩效对决

每个人在学习Activiti时都会一直问到的问题&#xff0c;与软件开发本身一样古老&#xff1a;“它如何执行&#xff1f;”。 到现在为止&#xff0c;当您问我同样的问题时&#xff0c;我将告诉您Activiti如何以各种可能的方式最小化数据库访问&#xff0c;如何将流程结构分解为“…

Java线程死锁–案例研究

本文将描述从在IBM JVM 1.6上运行的Weblogic 11g生产系统中观察到的最新Java死锁问题的完整根本原因分析。 此案例研究还将证明掌握线程转储分析技能的重要性&#xff1b; 包括用于IBM JVM Thread Dump格式。 环境规格 – Java EE服务器&#xff1a;Oracle Weblogic Server 1…

bzoj1968: [Ahoi2005]COMMON 约数研究

水题。。。 #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define rep(i,s,t) for(int is;i<t;i) int main(){int ans0,n;scanf("%d",&n);rep(i,1,n) ansn/i;printf("%d\n…

mysql查询某张表的所有外键_oracle中查询所有外键引用到某张表的记录

欢迎进入Oracle社区论坛&#xff0c;与200万技术人员互动交流 >>进入 oracle中查询所有外键引用到某张表的记录 //查询表的主键约束名 select * from user_constraints e where e.table_name表名;--输入 //查询所有引用到该主键的记录 select b.table_name,b.column_欢迎…

BTrace for Java应用程序简介

本文的目的是学习如何使用BTrace动态跟踪/观察正在运行的Java应用程序&#xff08;JDK 6&#xff09;&#xff0c;而无需更改应用程序的代码和配置参数。 什么是BTrace&#xff1f; BTrace是一个开源项目&#xff0c;始于2007年&#xff0c;最初由A.Sundararajan和K.Balasubra…

在Akka中实现主从/网格计算模式

主从模式是容错和并行计算的主要示例。 模式背后的想法是将工作划分为相同的子任务&#xff0c;然后将其委派给从属。 这些从节点或实例将处理工作任务&#xff0c;并将结果发送回主节点。 然后主节点将编译从所有从节点接收到的结果。关键是从节点仅知道如何处理任务&#xff…

react实现路由跳转_react实现hash路由

众所周知&#xff0c;目前单页面使用的路由有两种实现方式&#xff1a;hash 模式history 模式hash 模式路由原理&#xff1a;我们先来看hash模式&#xff0c;页面首次加载时需要在load事件中解析初始的URL&#xff0c;从而展示进入的页面。当 # 后面的哈希值发生变化时&#xf…