構建一個簡單的Java框架來測量并發執行任務的時間

文章目錄

  • 一、完整代碼
  • 二、代碼解釋
    • 1、方法簽名
    • 2、初始化CountDownLatch
    • 3、提交任務到執行器
    • 4、任務線程的邏輯
    • 5、主線程的邏輯
    • 詳細解釋
    • 總結

以下代碼實現了一個簡單的框架,用于測量并發執行任務的時間。它使用了Executor來執行任務,并通過CountDownLatch來協調多個線程的執行。

假設我們使用一個簡單的任務(如打印線程名稱和任務編號),并運行這個方法。

一、完整代碼

import java.util.concurrent.*;// Simple framework for timing concurrent execution
public static long time(Executor executor, int concurrency, Runnable action) throws InterruptedException {// 創建一個計數器,用于確保所有任務線程都已準備好CountDownLatch ready = new CountDownLatch(concurrency);// 創建一個計數器,用于通知所有任務線程開始執行CountDownLatch start = new CountDownLatch(1);// 創建一個計數器,用于確保所有任務線程都已完成CountDownLatch done = new CountDownLatch(concurrency);// 提交 concurrency 個任務到執行器for (int i = 0; i < concurrency; i++) {executor.execute(() -> {// 每個任務線程在開始執行前調用 countDown,表示已準備好ready.countDown(); // Tell timer we're readytry {// 每個任務線程等待 start 的計數器變為 0,即等待主線程通知開始執行start.await(); // Wait till peers are ready// 執行傳入的 Runnable 任務action.run();} catch (InterruptedException e) {// 如果捕獲到 InterruptedException,重新設置當前線程的中斷狀態Thread.currentThread().interrupt();} finally {// 每個任務線程執行完畢后,調用 countDown,表示已完成done.countDown(); // Tell timer we're done}});}// 主線程等待所有任務線程都準備好ready.await(); // Wait for all workers to be ready// 記錄開始時間long startNanos = System.nanoTime();// 主線程通知所有任務線程開始執行start.countDown(); // And they're off!// 主線程等待所有任務線程都完成done.await(); // Wait for all workers to finish// 計算并返回任務執行的總時間(納秒)return System.nanoTime() - startNanos;
}

為了更直觀地理解這段代碼的運行邏輯和輸出效果,我們可以補充具體的輸入參數,并展示完整的運行過程和最終輸出。假設我們使用一個簡單的任務(如打印線程名稱和任務編號),并運行這個方法。

import java.util.concurrent.*;public class ConcurrentTimingFramework {// Simple framework for timing concurrent executionpublic static long time(Executor executor, int concurrency, Runnable action) throws InterruptedException {// 創建一個計數器,用于確保所有任務線程都已準備好CountDownLatch ready = new CountDownLatch(concurrency);// 創建一個計數器,用于通知所有任務線程開始執行CountDownLatch start = new CountDownLatch(1);// 創建一個計數器,用于確保所有任務線程都已完成CountDownLatch done = new CountDownLatch(concurrency);// 提交 concurrency 個任務到執行器for (int i = 0; i < concurrency; i++) {executor.execute(() -> {// 每個任務線程在開始執行前調用 countDown,表示已準備好ready.countDown(); // Tell timer we're readytry {// 每個任務線程等待 start 的計數器變為 0,即等待主線程通知開始執行start.await(); // Wait till peers are ready// 執行傳入的 Runnable 任務action.run();} catch (InterruptedException e) {// 如果捕獲到 InterruptedException,重新設置當前線程的中斷狀態Thread.currentThread().interrupt();} finally {// 每個任務線程執行完畢后,調用 countDown,表示已完成done.countDown(); // Tell timer we're done}});}// 主線程等待所有任務線程都準備好ready.await(); // Wait for all workers to be ready// 記錄開始時間long startNanos = System.nanoTime();// 主線程通知所有任務線程開始執行start.countDown(); // And they're off!// 主線程等待所有任務線程都完成done.await(); // Wait for all workers to finish// 計算并返回任務執行的總時間(納秒)return System.nanoTime() - startNanos;}public static void main(String[] args) throws InterruptedException {// 創建一個線程池,線程池大小為 4ExecutorService executor = Executors.newFixedThreadPool(4);// 定義并發級別int concurrency = 4;// 定義要執行的任務Runnable action = () -> {System.out.println("Task executed by " + Thread.currentThread().getName());};// 調用 time 方法,測量并發執行的時間long duration = time(executor, concurrency, action);// 打印執行時間System.out.println("Total execution time: " + duration + " nanoseconds");// 關閉線程池executor.shutdown();}
}

假設運行環境中有足夠的線程資源,輸出可能如下:

Task executed by pool-1-thread-1
Task executed by pool-1-thread-2
Task executed by pool-1-thread-3
Task executed by pool-1-thread-4
Total execution time: 1234567 nanoseconds

二、代碼解釋

1、方法簽名

public static long time(Executor executor, int concurrency, Runnable action) throws InterruptedException {

參數:

  • Executor executor:一個執行器,用于執行任務。
  • int concurrency:并發級別,即同時運行的任務數量。
  • Runnable action:要執行的任務。
  • 返回值:long,表示任務執行的總時間(納秒)。
  • 異常:throws InterruptedException,表示方法可能會拋出InterruptedException。

2、初始化CountDownLatch

CountDownLatch ready = new CountDownLatch(concurrency);
CountDownLatch start = new CountDownLatch(1);
CountDownLatch done = new CountDownLatch(concurrency);
  • ready:用于確保所有任務線程都已準備好。
  • start:用于通知所有任務線程開始執行。
  • done:用于確保所有任務線程都已完成。

3、提交任務到執行器

for (int i = 0; i < concurrency; i++) {executor.execute(() -> {
  • 提交concurrency個任務到executor。
  • 每個任務是一個Runnable,使用Lambda表達式實現。

4、任務線程的邏輯

ready.countDown(); // Tell timer we're ready
try {start.await(); // Wait till peers are readyaction.run();
} catch (InterruptedException e) {Thread.currentThread().interrupt();
} finally {done.countDown(); // Tell timer we're done
}
  • ready.countDown():每個任務線程在開始執行前調用countDown,表示已準備好。
  • start.await():任務線程等待start的計數器變為0,即等待主線程通知開始執行。
  • action.run():執行傳入的Runnable任務。
  • catch (InterruptedException e):捕獲InterruptedException,并重新設置當前線程的中斷狀態。
  • done.countDown():任務線程執行完畢后,調用countDown,表示已完成。

5、主線程的邏輯

ready.await(); // Wait for all workers to be ready
long startNanos = System.nanoTime();
start.countDown(); // And they're off!
done.await(); // Wait for all workers to finish
return System.nanoTime() - startNanos;
  • ready.await():主線程等待所有任務線程都準備好。
  • startNanos = System.nanoTime():記錄開始時間。
  • start.countDown():主線程通知所有任務線程開始執行。
  • done.await():主線程等待所有任務線程都完成。
  • return System.nanoTime() - startNanos:計算并返回任務執行的總時間(納秒)。

詳細解釋

  • 任務線程的準備階段:
    每個任務線程調用ready.countDown(),表示已準備好。
    主線程調用ready.await(),等待所有任務線程準備好。
  • 任務線程的執行階段:
    主線程調用start.countDown(),通知所有任務線程開始執行。
    每個任務線程調用start.await(),等待主線程的通知。
    任務線程執行action.run(),打印當前線程的名稱。
  • 任務線程的完成階段:
    每個任務線程調用done.countDown(),表示已完成。
    主線程調用done.await(),等待所有任務線程完成。
  • 計算執行時間:
    主線程記錄任務開始時間和結束時間,計算總時間并返回。

總結

通過這個示例,我們可以看到time方法如何使用CountDownLatch來協調多個任務線程的執行,并測量任務的總執行時間。希望這個詳細的解釋和示例能幫助你更好地理解代碼的運行邏輯和輸出效果!

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

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

相關文章

精通 triton 使用 MLIR 的源碼邏輯 - 第001節:triton 的應用簡介

項目使用到 MLIR&#xff0c;通過了解 triton 對 MLIR 的使用&#xff0c;體會到 MLIR 在較大項目中的使用方式&#xff0c;匯總一下。1. Triton 概述OpenAI Triton 是一個開源的編程語言和編譯器&#xff0c;旨在簡化 GPU 高性能計算&#xff08;HPC&#xff09; 的開發&#…

Python爬蟲-政務網站自動采集數據框架

前言 本文是該專欄的第81篇,后面會持續分享python爬蟲干貨知識,記得關注。 本文,筆者將詳細介紹一個基于政務網站進行自動采集數據的爬蟲框架。對此感興趣的同學,千萬別錯過。 廢話不多說,具體細節部分以及詳細思路邏輯,跟著筆者直接往下看正文部分。(附帶框架完整代碼…

GitHub 趨勢日報 (2025年07月19日)

&#x1f4ca; 由 TrendForge 系統生成 | &#x1f310; https://trendforge.devlive.org/ &#x1f310; 本日報中的項目描述已自動翻譯為中文 &#x1f4c8; 今日獲星趨勢圖 今日獲星趨勢圖1054shadPS4695n8n361remote-jobs321maigret257github-mcp-server249open_deep_res…

2025開源組件安全工具推薦OpenSCA

OpenSCA是國內最早的開源SCA平臺&#xff0c;繼承了商業級SCA的開源應用安全缺陷檢測、多級開源依賴挖掘、縱深代碼同源檢測等核心能力&#xff0c;通過軟件成分分析、依賴分析、特征分析、引用識別、合規分析等方法&#xff0c;深度挖掘組件中潛藏的各類安全漏洞及開源協議風險…

旅游管理實訓基地建設:筑牢文旅人才培養的實踐基石

隨著文旅產業的蓬勃發展&#xff0c;行業對高素質、強實踐的旅游管理人才需求日益迫切。旅游管理實訓基地建設作為連接理論教學與行業實踐的關鍵紐帶&#xff0c;既是深化產教融合的重要載體&#xff0c;也是提升旅游管理專業人才培養質量的核心抓手。一、旅游管理實訓基地建設…

網絡爬蟲的相關知識和操作

介紹 爬蟲的定義 爬蟲&#xff08;Web Crawler&#xff09;是一種自動化程序&#xff0c;用于從互聯網上抓取、提取和存儲網頁數據。其核心功能是模擬人類瀏覽行為&#xff0c;訪問目標網站并解析頁面內容&#xff0c;最終將結構化數據保存到本地或數據庫。 爬蟲的工作原理 …

【vue-6】Vue3 響應式數據聲明:深入理解 ref()

在 Vue3 的 Composition API 中&#xff0c;ref() 是最基礎也是最常用的響應式數據聲明方式之一。它為開發者提供了一種簡單而強大的方式來管理組件狀態。本文將深入探討 ref() 的工作原理、使用場景以及最佳實踐。 1. 什么是 ref()&#xff1f; ref() 是 Vue3 提供的一個函數&…

HTML常用標簽匯總(精簡版)

<!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>簡單標記</title> </head><body>&…

【.net core】支持通過屬性名稱索引的泛型包裝類

類/// <summary> /// 支持通過屬性名稱索引的泛型包裝類 /// </summary> public class PropertyIndexer<T> : IEnumerable<T> {private T[] _items;private T _instance;private PropertyInfo[] _properties;private bool _caseSensitive;public Prope…

【機器學習|學習筆記】詳解支持向量機(Support Vector Machine,SVM)為何要引入核函數?為何對缺失數據敏感?

【機器學習|學習筆記】詳解支持向量機(Support Vector Machine,SVM)為何要引入核函數?為何對缺失數據敏感? 【機器學習|學習筆記】詳解支持向量機(Support Vector Machine,SVM)為何要引入核函數?為何對缺失數據敏感? 文章目錄 【機器學習|學習筆記】詳解支持向量機(…

Bicep入門篇

前言 Azure Bicep 是 ARM 模板的最新版本,旨在解決開發人員在將資源部署到 Azure 時遇到的一些問題。它是一款開源工具,實際上是一種領域特定語言 (DSL),它提供了一種聲明式編寫基礎架構的方法,該基礎架構描述了虛擬機、Web 應用和網絡接口等云資源的拓撲結構。它還鼓勵在…

命名實體識別15年研究全景:從規則到機器學習的演進(1991-2006)

本文精讀NRC Canada與NYU聯合發表的經典綜述《A survey of named entity recognition and classification》&#xff0c;解析NERC技術演進脈絡與核心方法論 一、為什么命名實體識別&#xff08;NER&#xff09;如此重要&#xff1f; 命名實體識別&#xff08;Named Entity Rec…

eNSP綜合實驗(DNCP、NAT、TELET、HTTP、DNS)

1搭建實驗拓撲2實驗目的學習掌握eNSP中的命令3實驗步驟3.1配置連接PC和客戶端的交換機(僅以右側為例)[Huawei]vlan batch 10 20 #創建vlan Info: This operation may take a few seconds. Please wait for a moment...done. [Huawei]un in en [Huawei]interface e0/0/2 [Huawei…

無人系統與安防監控中的超低延遲直播技術應用:基于大牛直播SDK的實戰分享

技術背景 在 無人機、機器人 以及 智能安防 等高要求行業&#xff0c;高清視頻的超低延遲傳輸 正在成為影響系統性能與業務決策的重要因素。無論是工業生產線的遠程巡檢、突發事件的應急響應&#xff0c;還是高風險環境下的智能監控與遠程控制&#xff0c;視頻鏈路的傳輸延遲都…

go語言學習之包

概念&#xff1a;在Go 語言中&#xff0c;包由一個或多個保存在同一目錄的源碼文件組成&#xff0c;包名宇目錄名無關&#xff0c;但是通常大家習慣包名和目錄名保持一致&#xff0c;同一目錄的源碼文件必須使用相同的包名。包的用途類似于其他語言的命名空間&#xff0c;可以限…

pytorch學習筆記(五)-- 計算機視覺的遷移學習

系列文章目錄 pytorch學習筆記&#xff08;一&#xff09;-- pytorch深度學習框架基本知識了解 pytorch學習筆記&#xff08;二&#xff09;-- pytorch模型開發步驟詳解 pytorch學習筆記&#xff08;三&#xff09;-- TensorBoard的介紹 pytorch學習筆記&#xff08;四&…

數字IC后端培訓教程之數字后端項目典型項目案例解析

數字IC后端低功耗設計實現案例分享(3個power domain&#xff0c;2個voltage domain) Q1: 電路如下圖&#xff0c;clk是一個很慢的時鐘test_clk&#xff08;屬于DFT的)&#xff0c;DFF1與and 形成一個clock gating check。跑pr 發現&#xff0c;時鐘樹綜合CTS階段&#xff08;C…

2025 Data Whale x PyTorch 安裝學習筆記(Windows 版)

一、Anaconda 的安裝與基本操作 1. 安裝 Anaconda/miniconda 官方鏈接&#xff1a;Anaconda | Individual Edition 根據系統版本選擇合適的安裝包下載并安裝。 2. 檢驗安裝 打開 “開始” 菜單&#xff0c;找到 “Anaconda Prompt”&#xff08;一般在 Anaconda3 文件夾…

mac OS上docker安裝zookeeper

拉取鏡像&#xff1a;$ docker pull zookeeper:3.5.7 3.5.7: Pulling from library/zookeeper 3.5.7: Pulling from library/zookeeper 3.5.7: Pulling from library/zookeeper no matching manifest for linux/arm64/v8 in the manifest list entries報錯&#xff1a;由于時M3…

設備通過4G網卡接入EasyCVR視頻融合平臺,出現無法播放的問題排查和解決

EasyCVR視頻融合平臺作為支持多協議接入、多設備集中管理的綜合性視頻解決方案&#xff0c;可實現各類終端設備的視頻流匯聚與實時播放。近期收到用戶反饋&#xff0c;在EasyCVR平臺接入設備后出現視頻流無法播放的情況。為幫助更多用戶快速排查同類問題&#xff0c;現將具體處…