我不久前参与了一个项目,该项目的报告流程如下:

  1. 用户会要求举报
  2. 报告要求将被翻译成较小的部分
  3. 每个零件的报告将基于零件/节的类型由报告生成器生成
  4. 组成报告的各个部分将重新组合成最终报告,并返回给用户

我的目标是展示如何从错误的实施过渡到相当好的实施:
单元测试最好地展示了我拥有的一些基本构建基块:这是一个测试助手,它生成示例报告请求,其中包括组成报告请求部分:

public class FixtureGenerator {public static ReportRequest generateReportRequest(){List<ReportRequestPart> requestParts = new ArrayList<ReportRequestPart>();Map<String, String> attributes = new HashMap<String, String>();attributes.put("user","user");Context context = new Context(attributes );ReportRequestPart part1 = new ReportRequestPart(Section.HEADER, context);ReportRequestPart part2 = new ReportRequestPart(Section.SECTION1, context);ReportRequestPart part3 = new ReportRequestPart(Section.SECTION2, context);ReportRequestPart part4 = new ReportRequestPart(Section.SECTION3, context);ReportRequestPart part5 = new ReportRequestPart(Section.FOOTER, context);   requestParts.add(part1);        requestParts.add(part2);requestParts.add(part3);requestParts.add(part4);requestParts.add(part5);ReportRequest reportRequest  = new ReportRequest(requestParts );return reportRequest;}}

以及生成报告的测试:

public class FixtureGenerator {@Testpublic void testSequentialReportGeneratorTime(){long startTime = System.currentTimeMillis();Report report = this.reportGenerator.generateReport(FixtureGenerator.generateReportRequest());long timeForReport = System.currentTimeMillis()-startTime;assertThat(report.getSectionReports().size(), is (5));logger.error(String.format("Sequential Report Generator : %s ms", timeForReport));}

生成报告一部分的组件是一个虚拟实现,具有2秒的延迟以模拟IO密集调用:

public class DummyReportPartGenerator implements ReportPartGenerator{@Overridepublic ReportPart generateReportPart(ReportRequestPart reportRequestPart) {try {//Deliberately introduce a delayThread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}return new ReportPart(reportRequestPart.getSection(), "Report for " + reportRequestPart.getSection());}
}

顺序执行
 
给定这些基本的类集,我的第一个天真的顺序实现如下:

public class SequentialReportGenerator implements ReportGenerator {private ReportPartGenerator reportPartGenerator;@Overridepublic Report generateReport(ReportRequest reportRequest){List<ReportRequestPart> reportRequestParts = reportRequest.getRequestParts();List<ReportPart> reportSections = new ArrayList<ReportPart>();for (ReportRequestPart reportRequestPart: reportRequestParts){reportSections.add(reportPartGenerator.generateReportPart(reportRequestPart));}return new Report(reportSections);}......
}

显然,对于其中包含5个部分的报告请求,每个部分需要2秒钟才能完成,此报告大约需要10秒钟才能返回给用户。

它请求同时进行。

基于原始线程的实现
 
以下是第一个并发实现,虽然不好,但比顺序的要好,其后是为每个报告请求部分生成一个线程,等待要生成的报告部分(使用thread.join()方法),并在出现这些块时对其进行汇总在。

public class RawThreadBasedReportGenerator implements ReportGenerator {private static final Logger logger = LoggerFactory.getLogger(RawThreadBasedReportGenerator.class);private ReportPartGenerator reportPartGenerator;@Overridepublic Report generateReport(ReportRequest reportRequest) {List<ReportRequestPart> reportRequestParts = reportRequest.getRequestParts();List<Thread> threads = new ArrayList<Thread>();List<ReportPartRequestRunnable> runnablesList = new ArrayList<ReportPartRequestRunnable>();for (ReportRequestPart reportRequestPart : reportRequestParts) {ReportPartRequestRunnable reportPartRequestRunnable = new ReportPartRequestRunnable(reportRequestPart, reportPartGenerator);runnablesList.add(reportPartRequestRunnable);Thread thread = new Thread(reportPartRequestRunnable);threads.add(thread);thread.start();}for (Thread thread : threads) {try {thread.join();} catch (InterruptedException e) {logger.error(e.getMessage(), e);}}List<ReportPart> reportParts = new ArrayList<ReportPart>();for (ReportPartRequestRunnable reportPartRequestRunnable : runnablesList) {reportParts.add(reportPartRequestRunnable.getReportPart());}return new Report(reportParts);}    .....
}

这种方法的危险在于,将为每个报表部件创建一个新线程,因此在实际情况下,如果同时发出100个请求,并且每个请求都产生5个线程,则可能最终在vm中创建500个代价高昂的线程!!

因此,必须以某种方式限制线程的创建。 在下一篇博客文章中,我将介绍另外两种控制线程的方法。

参考: 并发–来自JCG合作伙伴 Biju Kunjummen的all和杂物博客, 并发-顺序和原始线程 。

翻译自: https://www.javacodegeeks.com/2012/07/concurrency-sequential-and-raw-thread.html

并发–顺序线程和原始线程相关推荐

  1. 线程并发库和线程池的作用_并发–顺序线程和原始线程

    线程并发库和线程池的作用 不久前,我参与了一个项目,该项目的报告流程如下: 用户会要求举报 报告要求将被翻译成较小的部分 基于零件/节的类型的每个零件的报告将由报告生成器生成 组成报告的各个部分将重新 ...

  2. 「Python-StandardLib」第十六章:并发执行( Cocurrent Executing,线程、多线程队列、子进程)

    参考链接: python多线程 python线程--基于线程的并行 16.1 线程(threading) ps: python ver. is 2.7.18 线程是一项将非连续依赖任务进行分解的技术. ...

  3. Java并发编程与技术内幕:线程池深入理解

    林炳文Evankaka原创作品.转载请注明出处http://blog.csdn.net/evankaka 摘要: 本文主要讲了Java当中的线程池的使用方法.注意事项及其实现源码实现原理,并辅以实例加 ...

  4. 多线程、并发/并行、自定义线程类、线程安全、守护线程、定时器、线程状态、线程池

    目录 进程和线程: 进程: 线程: 多线程的好处: 线程调度: 分时调度: 抢占式调度: 并发与并行: 线程的生命周期: 实现线程的两种基本方式(还有第三种): 创建Thread线程类: 创建Runn ...

  5. 并发编程(进程、线程、协程)

    操作系统 一 为什么要有操作系统? 现代计算机系统是由一个或者多个处理器,主存,磁盘,打印机,键盘,鼠标显示器,网络接口以及各种其他输入输出设备组成的复杂系统,每位程序员不可能掌握所有系统实现的细节, ...

  6. [Java并发编程(一)] 线程池 FixedThreadPool vs CachedThreadPool ...

    [Java并发编程(一)] 线程池 FixedThreadPool vs CachedThreadPool ... 摘要 介绍 Java 并发包里的几个主要 ExecutorService . 正文 ...

  7. Java 并发编程——Executor框架和线程池原理

    Java 并发编程系列文章 Java 并发基础--线程安全性 Java 并发编程--Callable+Future+FutureTask java 并发编程--Thread 源码重新学习 java并发 ...

  8. [Java并发编程(二)] 线程池 FixedThreadPool、CachedThreadPool、ForkJoinPool?为后台任务选择合适的 Java executors...

    [Java并发编程(二)] 线程池 FixedThreadPool.CachedThreadPool.ForkJoinPool?为后台任务选择合适的 Java executors ... 摘要 Jav ...

  9. Java并发 正确终止与恢复线程

    为什么80%的码农都做不了架构师?>>>    前面提到了stop().suspend()等方法在终止与恢复线程的弊端,那么问题来了,应该如何正确终止与恢复线程呢?这里可以使用两种方 ...

最新文章

  1. stm32 文件系统dma大小_「正点原子NANO STM32F103开发板资料连载」第二十二章 DMA 实验...
  2. 互联网1分钟 |1128
  3. 数学--数论--同余及其性质(超详细)
  4. 计算器java程序设计报告总体设计,java程序设计实验报告-计算器
  5. 产品采用的即时通讯软件是本地云架构
  6. 王立平--android事件监听的3种方式
  7. 2021-2025年中国定时控制器行业市场供需与战略研究报告
  8. Easy UI combobox实现类似 Select2的效果,下拉带搜索框
  9. 微信游戏推荐系统大揭秘
  10. Android集成阿里热修复(Hotfix)
  11. 读写算杂志读写算杂志社读写算编辑部2022年第16期目录
  12. 如何保证战略落地_【管理前沿】保障战略规划落地的三大措施
  13. adobe xd 白屏闪退 终极拯救方法
  14. Python 简单编写一个注册邮箱
  15. 大数据必学Java知识(一):Java基础入门语法和安装
  16. LVS DR模式负载均衡
  17. “时间都到哪里去了?”
  18. python进行JB正态性检验
  19. 当效益不好的时候为什么公司选择裁员,而不是降薪
  20. 中国全国城市列表JSON数据2022最新

热门文章

  1. tomcat(6)生命周期
  2. 纯干货,Spring-data-jpa详解,全方位介绍。
  3. aws lambda使用_使用AWS Lambda的CloudWatch事件通知
  4. 写java代码时的注意事项_从方法返回Java 8的可选项时的注意事项
  5. java设计模式迭代器模式_迭代器设计模式示例
  6. 使用Spring WebFlux构建反应性REST API –第1部分
  7. osgi架构与linux_OSGi:进入微服务架构的门户
  8. lucene索引_在崩溃或断电后测试Lucene的索引耐久性
  9. java文件序列化_通过快速Java和文件序列化加快速度
  10. jboss7.1.1 部署_在JBoss AS 7上部署BroadleafCommerce 2.0