1. <nobr id="easjo"><address id="easjo"></address></nobr>

      <track id="easjo"><source id="easjo"></source></track>
      1. 
        

      2. <bdo id="easjo"><optgroup id="easjo"></optgroup></bdo>
      3. <track id="easjo"><source id="easjo"><em id="easjo"></em></source></track><option id="easjo"><span id="easjo"><em id="easjo"></em></span></option>
          貴州做網站公司
          貴州做網站公司~專業!靠譜!
          10年網站模板開發經驗,熟悉國內外開源網站程序,包括DEDECMS,WordPress,ZBlog,Discuz! 等網站程序,可為您提供網站建設,網站克隆,仿站,網頁設計,網站制作,網站推廣優化等服務。我們專注高端營銷型網站,企業官網,集團官網,自適應網站,手機網站,網絡營銷,網站優化,網站服務器環境搭建以及托管運維等。為客戶提供一站式網站解決方案?。?!

          CountDownLatch詳解以及用法示例

          來源:互聯網轉載 時間:2023-09-10 01:19:36

          一、什么是CountDownLatch

          CountDownLatch中count down是倒數的意思,latch則是門閂的含義。整體含義可以理解為倒數的門栓,似乎有一點“三二一,芝麻開門”的感覺。

          CountDownLatch的作用也是如此,在構造CountDownLatch(int count):的時候需要傳入一個整數count,在這個整數“倒數”到0之前,主線程需要等待在門口,而這個“倒數”過程則是由各個執行線程驅動的,每個線程執行完一個任務“倒數”一次。

          總結來說,CountDownLatch的作用就是等待其他的線程都執行完任務,必要時可以對各個任務的執行結果進行匯總,然后主線程才繼續往下執行。

          二、主要方法

        1. CountDownLatch(int count):構造方法,創建一個新的 CountDownLatch 實例,用給定的計數初始化。參數 count 表示線程需要等待的任務數量。
        2. int numberOfTasks = 5; CountDownLatch latch = new CountDownLatch(numberOfTasks);
        3. void await():使當前線程等待,直到計數器值變為0,除非線程被 interrupted。如果計數器的值已經為0,則此方法立即返回。在實際應用中,通常在主線程中調用此方法,等待其他子線程完成任務。
        4. latch.await();
        5. boolean await(long timeout, TimeUnit unit):使當前線程等待,直到計數器值變為0,或者指定的等待時間已到,或者線程被 interrupted。如果計數器的值已經為0,則此方法立即返回。
          參數 timeout 是指定的等待時間,
          參數 unit 是 timeout 的單位(如秒、毫秒等)。
          此方法返回一個布爾值,表示在等待時間內計數器是否變為0。
        6. latch.await(5, TimeUnit.SECONDS);

          這里需要注意的是,await()方法并沒有規定只能有一個線程執行該方法,如果多個線程同時執行await()方法,那么這幾個線程都將處于等待狀態,并且以共享模式享有同一個鎖。

        7. void countDown():遞減計數器的值。如果計數器的結果為0, 則釋放所有等待的線程。在實際應用中,通常在線程完成任務后調用此方法。
        8. latch.countDown();

          這里需要注意的是,countDown()方法并沒有規定一個線程只能調用一次,當同一個線程調用多次countDown()方法時,每次都會使計數器減一;

        9. long getCount():獲取當前計數的值。返回當前 CountDownLatch 實例內部的計數值。
        10. long remainingCount = latch.getCount();

          三、優缺點

          • 優點:
          • 簡化了線程間的通信和同步。在某些并發場景中,需要等待其他線程完成任務后才能繼續執行,使用 CountDownLatch 可以簡化這種操作,而不需要復雜的鎖和等待/通知機制。
          • 提高性能。由于 CountDownLatch 可以讓線程在完成任務后立即遞減計數值,而不需要等待其他線程完成任務,因此可以減少阻塞,提高程序運行性能。
          • 支持靈活的計數??梢酝ㄟ^創建不同的 CountDownLatch 實例,實現對多個線程任務計數。

          • 缺點:
          • 單次使用。CountDownLatch 的計數值無法重置。一旦計數值到達零,它就不能再被使用了。在需要重復使用的場景中,可以選用 CyclicBarrier 或 semaphore。
          • 沒有返回值。CountDownLatch 無法獲得執行任務的線程所返回的結果。如果需要收集線程執行結果,可以考慮使用 java.util.concurrent.Future 和 java.util.concurrent.ExecutorService。

          四、使用場景

        11. 啟動多個線程執行并行任務,主線程等待所有并行任務完成后繼續執行。
          例如:在測試中,準備數據階段,需要同時查詢多個子系統的數據和處理,等待處理結束后再進行下一步操作。
        12. 控制線程的執行順序。一個線程需要等待其他線程的結果或者完成任務后才能繼續執行。
          例如:一個文件解壓縮程序,首先需要下載文件,下載完成后解壓文件。
        13. 實現一個計數器,允許一個或多個線程等待直到計數器為0。這對于在系統初始化時,需要等待資源加載或者初始化的場景十分有用。
          例如:等待加載配置文件、啟動連接池等操作完成后才開始處理其他任務。
        14. 四、示例代碼

          4.1 示例代碼

          下面的示例展示了一個簡單的網站爬蟲,它使用 CountDownLatch 在主線程中等待其他爬蟲線程完成任務。

          在這個例子中,我們要爬取一組網站的內容,在主線程中等待所有爬蟲任務完成。

          首先,我們創建一個 URLs 列表,包含多個網站 URL。

          然后,我們使用 CountDownLatch 實例 latch 來跟蹤待完成的爬蟲任務數量。

          接著,我們遍歷 URL 列表,為每個 URL 創建一個新的 Crawler 線程。Crawler 類實現了 Runnable 接口,用于讀取指定 URL 的網頁內容。在完成任務后,它調用 latch.countDown() 方法減少計數值。

          最后,在主線程中,我們調用 latch.await() 方法等待所有爬蟲線程完成任務。當所有任務完成時,打印一條消息表示爬蟲任務已完成。

          import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.URL; import java.util.ArrayList; import java.util.List; import java.util.concurrent.CountDownLatch;public class WebCrawler {private static class Crawler implements Runnable {private final String url;private final CountDownLatch latch;public Crawler(String url, CountDownLatch latch) {this.url = url;this.latch = latch;}@Overridepublic void run() {try {URL urlObject = new URL(url);BufferedReader in = new BufferedReader(new InputStreamReader(urlObject.openStream()));String inputLine;StringBuilder content = new StringBuilder();while ((inputLine = in.readLine()) != null) {content.append(inputLine);content.append("\n");}in.close();System.out.println("爬取 " + url + " 成功, 內容大小: " + content.length() + " 字符");} catch (Exception e) {System.err.println("爬取 " + url + " 失敗, 原因: " + e.getMessage());} finally {latch.countDown();}}}public static void main(String[] args) throws InterruptedException {List<String> urls = new ArrayList<>();urls.add("https://github.com/");urls.add("https://stackoverflow.com/");urls.add("https://www.zhihu.com/");urls.add("https://www.reddit.com/");urls.add("https://www.linkedin.com/");CountDownLatch latch = new CountDownLatch(urls.size());System.out.println("開始爬蟲任務...");for (String url : urls) {new Thread(new Crawler(url, latch)).start();}latch.await();System.out.println("所有爬蟲任務都已完成!");} }

          4.2 運行結果

          開始爬蟲任務... 爬取 https://www.zhihu.com/ 成功, 內容大小: 37783 字符 爬取 https://github.com/ 成功, 內容大小: 227576 字符 爬取 https://stackoverflow.com/ 成功, 內容大小: 171290 字符 爬取 https://www.linkedin.com/ 成功, 內容大小: 12603 字符 爬取 https://www.reddit.com/ 失敗, 原因: Read timed out 所有爬蟲任務都已完成!

          五、稍復雜點的示例代碼

          5.1 代碼示例講解

          這是一個稍復雜的 CountDownLatch 示例。

          在這個例子中,我們將模擬一個簡單的賽車游戲,

          • 其中有一個倒計時開始。
          • 一旦倒計時結束,賽車就開始比賽,
          • 當所有賽車完成比賽時,主線程打印一條消息。
          import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit;public class CountDownLatchAdvancedDemo {public static void main(String[] args) throws InterruptedException {int numberOfRacers = 5;CountDownLatch startSignal = new CountDownLatch(1);CountDownLatch finishSignal = new CountDownLatch(numberOfRacers);// 創建賽車線程for (int i = 0; i < numberOfRacers; i++) {new Thread(new Racer(startSignal, finishSignal)).start();}// 模擬倒計時System.out.println("倒計時開始...");for (int i = 3; i > 0; i--) {System.out.println("倒計時: " + i);TimeUnit.SECONDS.sleep(1);}System.out.println("比賽開始!");startSignal.countDown(); // 啟動信號// 等待所有賽車完成比賽finishSignal.await();System.out.println("所有賽車都完成了比賽!");}static class Racer implements Runnable {private CountDownLatch startSignal;private CountDownLatch finishSignal;public Racer(CountDownLatch startSignal, CountDownLatch finishSignal) {this.startSignal = startSignal;this.finishSignal = finishSignal;}@Overridepublic void run() {try {// 等待開始信號startSignal.await();// 正在比賽System.out.println(Thread.currentThread().getName() + " 開始比賽...");Thread.sleep((long) (Math.random() * 10000));System.out.println(Thread.currentThread().getName() + " 完成比賽!");} catch (InterruptedException e) {e.printStackTrace();} finally {// 完成比賽后,遞減完成信號計數finishSignal.countDown();}}} }

          在這個例子中,我們創建了兩個 CountDownLatch,

          • 一個用于開始信號 (startSignal),
          • 另一個用于完成信號 (finishSignal)。創建賽車線程時,它們都需要等待開始信號。

          當倒計時結束時,調用 startSignal.countDown(),開始信號變為0,并表示比賽開始。

          每個線程在模擬賽車完成比賽后,調用 finishSignal.countDown() 減少完成信號計數。

          主線程使用 finishSignal.await() 等待所有賽車線程都完成比賽。當計數值變為 0 時,主線程將打印一條消息表示所有賽車都完成了比賽。

          5.2 運行結果

          倒計時開始... 倒計時: 3 倒計時: 2 倒計時: 1 比賽開始! Thread-4 開始比賽... Thread-2 開始比賽... Thread-0 開始比賽... Thread-1 開始比賽... Thread-3 開始比賽... Thread-4 完成比賽! Thread-1 完成比賽! Thread-0 完成比賽! Thread-2 完成比賽! Thread-3 完成比賽! 所有賽車都完成了比賽!

          網絡推廣與網站優化公司(網絡優化與推廣專家)作為數字營銷領域的核心服務提供方,其價值在于通過技術手段與策略規劃幫助企業提升線上曝光度、用戶轉化率及品牌影響力。這...

          在當今數字化時代,公司網站已成為企業展示形象、傳遞信息和開展業務的重要平臺。然而,對于許多公司來說,網站建設的價格是一個關鍵考量因素。本文將圍繞“公司網站建設價...

          在當今的數字化時代,企業網站已成為企業展示形象、吸引客戶和開展業務的重要平臺。然而,對于許多中小企業來說,高昂的網站建設費用可能會成為其發展的瓶頸。幸運的是,隨...

          tendystar308藍牙耳機的密碼多少?tendystar308藍牙耳機的密碼默認為0000,無需修改。具體使用方法如下:1。新耳機開機后,會有語音提示自動搜索配對設備。此時,為手機和其他支持藍牙的設備打開藍牙。 2. 打開手機和其他設備上的可檢測性,即可以檢測附近的藍牙信號。然后搜索附近的藍牙信號,搜索藍牙耳機(一般會顯示藍牙耳機的型號),然后點擊連接。如果系統提示您輸入密碼,則默認值為00...

          e站app怎么用?E站應用程序是一樣的,通過手機號碼,你可以設置一個帳號和密碼,登錄使用使用一個叫“泡芙瀏覽器”的軟件。打開網站的正確方法-亨泰網如果您有帳戶,請直接登錄。如果你沒有賬戶,就注冊一個。2注冊過程非常簡單。首先單擊register,然后會出現一堆TOS。單擊“同意”注冊。三。輸入要注冊的用戶名(登錄賬號)和要顯示的名稱(類似昵稱),輸入并確認密碼和電子郵件,最后輸入要注冊的驗證碼。4...

          大興區工業開發區的郵編是多少?你是說大興經濟技術開發區吧?在亦莊開發區,郵編是100176。北京各區各地的郵編?東城區的郵政編碼是: 10萬東城區100000西城區100000朝陽區100000豐臺區100000石景山區100000海淀區100000門頭溝區102300房山區102400通州區101100順義區101300昌平區102200大興區102600懷柔區101400平谷區101200密云...

          TOP
          国产初高中生视频在线观看|亚洲一区中文|久久亚洲欧美国产精品|黄色网站入口免费进人
          1. <nobr id="easjo"><address id="easjo"></address></nobr>

              <track id="easjo"><source id="easjo"></source></track>
              1. 
                

              2. <bdo id="easjo"><optgroup id="easjo"></optgroup></bdo>
              3. <track id="easjo"><source id="easjo"><em id="easjo"></em></source></track><option id="easjo"><span id="easjo"><em id="easjo"></em></span></option>