并發–順序線程和原始線程

我不久前參與了一個項目,該項目的報告流程如下:
  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

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/372580.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/372580.shtml
英文地址,請注明出處:http://en.pswp.cn/news/372580.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

借貸期末余額 oracle,應交稅費期末余額分別在借貸方表示什么

應交稅費是負債類科目&#xff0c;有時期末余額會在借方&#xff0c;有時會在貸方。因此&#xff0c;小伙伴們在實際的賬務處理工作中&#xff0c;一定要弄清楚兩者的含義。為了幫助大家進行有更進一步的理解&#xff0c;小編再次匯總了應交稅費期末余額分別在借貸方表示什么的…

Android學習——ListView的緩存機制

在使用ListView的時候&#xff0c;需要加載適配器和數據源&#xff0c;這篇文章主要介紹一下ListView的使用以及利用ListView的緩存機制來減少系統的初始化時間。 ListView的使用 ListView和ViewPager很類似&#xff0c;首先在ArrayList中存放數據源&#xff0c;并把它作為Adap…

C#基礎 特殊集合(棧集合、隊列集合、哈希表集合)

一、 棧: Stank,先進先出&#xff0c;一個一個賦值&#xff0c;一個一個取值&#xff0c;按照順序。 .count 取集合內元素的個數 .push 將元素一個一個推入集合 .pop 將元素一個一個彈出集合 .peek 查看集合中的一個元素 .clear 清空集合 Stack stnew Stack…

OSGi環境中的Servlet基本身份驗證

您首先需要獲得對OSGI HTTP Service的引用。 您可以通過聲明性服務來做到這一點。 這篇文章將集中在獲得對HTTP服務的引用之后的步驟。 注意&#xff1a;此職位的完整課程位于此處 通過OSGI HTTP Service注冊Servlet時&#xff0c;它為您提供了提供HTTPContext實現的選項。 htt…

linux夏令時配置文件,Linux夏令時是怎么調整的?

以法國巴黎為例&#xff1a;root121 zoneinfo]# ln -s /usr/share/zoneinfo/Europe/Paris /etc/localtime[root121 zoneinfo]# date2015年 10月 13日 星期二 03:45:09 CEST[root121 zoneinfo]# date -RTue, 13 Oct 2015 03:45:31 0200[root121 zoneinfo]# zdump -v /etc/localt…

Kali Linux滲透基礎知識整理(二)漏洞掃描

Kali Linux滲透基礎知識整理系列文章回顧 漏洞掃描 網絡流量NmapHping3NessuswhatwebDirBusterjoomscanWPScan網絡流量 網絡流量就是網絡上傳輸的數據量。 TCP協議 TCP是因特網中的傳輸層協議&#xff0c;使用三次握手協議建立連接。當主動方發出SYN連接請求后&#xff0c;等待…

嵌入式軟件設計第09實驗報告

學號&#xff1a;140201133 姓名&#xff1a;李宇昕 組別&#xff1a;第3組 實驗地點&#xff1a;D19 一、實驗目的&#xff1a; 1.熟悉WWW技術中的SSI&#xff08;Server Side Include&#xff09;技術。 2.學會使用SSI技術編寫代碼把當前開發板內…

TeamCity工件:HTTP,Ant,Gradle和Maven

您可以通過幾種方式檢索TeamCity工件&#xff1f; 我說有很多選擇 &#xff01; 如果您使用的是Java構建工具&#xff0c;那么可以使用簡單的HTTP請求&#xff0c;Ant Ivy&#xff0c;Gradle和Maven下載和使用TeamCity構建配置生成的二進制文件。 怎么樣&#xff1f; 繼續閱讀…

linux中hadoop命令大全,hadoop常用命令

啟動Hadoop進入HADOOP_HOME目錄。執行sh bin/start-all.sh關閉Hadoop進入HADOOP_HOME目錄。執行sh bin/stop-all.sh1、查看指定目錄下內容hadoop dfs –ls [文件目錄]eg: hadoop dfs –ls /user/wangkai.pt2、打開某個已存在文件hadoop dfs –cat [file_path]eg:hadoop dfs -ca…

Uber從Postgres切換到MySQL

Uber工程師在官方博客上描述了他們為什么要從 Postgres 切換到 MySQL 數據庫。Uber的早期架構是由 Python編寫的后端應用構成&#xff0c;使用了 Postgres 數據庫。但此后&#xff0c;Uber的架構發生了顯著的改變&#xff0c;轉變到了微服務模型和新的數據平臺。以前他們使用 P…

AutoCAD如何方便截圖放到Word文檔,改成白底黑字

將模型視圖切換到布局2即可 比如下圖所示的效果 先回到模型視圖把所有線條顏色都改成白色&#xff0c;然后添加適當的標注&#xff08;比如要受力分析&#xff0c;則在CAD中繪制箭頭也很方便的&#xff09;&#xff0c;文字說明。然后切換到布局2就OK 可以截圖了。 轉載于:http…

在Hotspot JVM中跟蹤過多的垃圾回收

由于內存泄漏或其他內存問題&#xff0c;經常導致應用程序凍結&#xff0c;僅使垃圾收集器&#xff08;GC&#xff09;進程運行失敗&#xff0c;試圖釋放一些空間。 直到看門狗&#xff08;或沮喪的管理員&#xff09;重新啟動應用程序并且問題從未解決之前&#xff0c;這種情況…

linux 網絡在線升級,linux在線升級

//前提信息&#xff1a;1.系統分區信息SPI-Flash:[0] 0x000000000000-0x000000020000 : "SPL,128KB"[1] 0x000000020000-0x0000000e0000 : "U-Boot,768KB"[2] 0x0000000e0000-0x000000100000 : "U-Boot Env,128KB"[3] 0x000000100000-0x00000020…

XML反序列化出錯,XML 文檔(2, 2)中有錯誤

XML轉換為實體類的錯誤處理方案 一.錯誤描述&#xff1a; XML反序列化出錯&#xff0c;XML 文檔(2, 2)中有錯誤二.解決方案&#xff1a; 在實體類的字段要加上XmlElement屬性三.具體實現: 1.XML文檔 <EVENT_INSTANCE><EventType>ALTER_TABLE</EventType><…

iOS--支付寶環境集成

1.下載支付寶SDK以及Demo https://doc.open.alipay.com/doc2/detail?treeId54&articleId103419&docType1 2.新建文件夾“AliSDK”&#xff0c;將壓縮包內的文件拷貝到該文件夾下&#xff0c;完成后如下圖所示&#xff1a; 3.將文件夾拷貝到項目中&#xff0c; 4.執行完…

再見,再見,5 * 60 * 1000 //五分鐘,再見,再見

在這篇文章中&#xff0c;我將討論一個在1.5版中首次引入的類&#xff0c;我使用了太多&#xff0c;但是與一些人交談&#xff0c;他們說他們不知道它的存在。 此類是TimeUnit 。 TimeUnit類表示給定粒度單位的持續時間&#xff0c;還提供了轉換為不同單位的實用方法以及執行計…

windows如何調用Linux的API,Windows和Native API中的系統調用?

最近&#xff0c;我在* NIX操作系統中使用了很多匯編語言。我想知道Windows域。Linux中的調用約定&#xff1a;mov $SYS_Call_NUM, %eaxmov $param1 , %ebxmov $param2 , %ecxint $0x80而已。這就是我們應該如何在Linux中進行系統調用。linux中所有系統調用的參考&#xff1a;關…

maven生命周期和插件

maven生命周期和插件 生命周期 maven的生命周期有三套&#xff0c;互相獨立。每個生命周期含有不同階段&#xff0c;常用如下 clean 清理項目 pre-clean 執行清理前需要完成的工作clean 清理上一次構建生成的文件post-clean 執行清理后需要完成的工作default 構建項目 validate…

Java EE 6測試第二部分– Arquillian和ShrinkWrap簡介

在Java EE 6測試的第一部分中&#xff0c;我簡要介紹了使用Glassfish嵌入式容器的EJB 3.1 Embeddable API&#xff0c;以演示如何啟動該容器&#xff0c;如何在項目類路徑中查找bean以及運行非常簡單的集成測試。 這篇文章重點介紹Arquillian和ShrinkWrap以及為什么它們是用于企…

linux內存分配堆棧數據段代碼段,linux – LD_PRELOAD堆棧和數據段內存分配

你好,我正在編寫一個Linux模塊(基于名為“Ccontrol”的GitHub項目)來創建緩存分區(a.k.a頁面著色),以減輕定時側通道攻擊(用于防止Prime Probe等攻擊).我已經使用LD_PRELOAD系統env變量來覆蓋所有malloc(),calloc()和free()調用,并用顏色感知調用替換它們.現在我正在尋找顏色堆…