讓 3 個線程串行的幾種方式

1、通過join()的方式

子線程調用join()的時候,主線程等待子線程執行完再執行。如果讓多個線程順序執行的話,那么需要他們按順序調用start()。

   /*** - 第一個迭代(i=0):*     啟動線程t1 -> 然后調用t1.join()。*     主線程(執行testMethod2的線程)會在t1.join()處阻塞,直到t1線程執行完畢。* - 第二個迭代(i=1):*     只有等到t1執行完畢,主線程才會繼續執行,然后啟動線程t2,并調用t2.join(),主線程等待t2執行完畢。* - 第三個迭代(i=2):*     同樣,主線程等待t2執行完畢后,啟動t3,然后等待t3執行完畢。* @throws InterruptedException*/@Testvoid testMethod1() throws InterruptedException {List<Thread> list = new ArrayList<>();for (int i = 1; i <= 3; i++) {Thread thread = new Thread(() -> {log.info("{} 執行~", Thread.currentThread().getName());},"t" + i);list.add(thread);}for (int i = 0; i < list.size(); i++) {list.get(i).start();//他阻塞的是主線程,當前線程執行完后,主線程才會執行list.get(i).join();}}

2、通過CountDownLatch 的方式

countDown():沒調用一次,計數器就會減 1。當計數器減到 0 時,調用await()的線程才會被喚醒。
await():當計數器不為 0 的時候,調用await()的線程會被阻塞。

   /***  1、讓第一個線程執行,完事調用countDown()再對countDownLatch記數減 1*  2、第二個線程調用await()去喚醒,但是需要線程一執行完,*     因為只有記數為 0 的話,當前線程才會被喚醒,依次類推*/@Testvoid testMethod2(){CountDownLatch countDownLatch = new CountDownLatch(1);for (int i = 1; i <= 3; i++) {final int threadId = i;new Thread(() -> {if (threadId != 1) {try {//等待計數器歸零,再繼續往下執行,否則在此處阻塞countDownLatch.await();} catch (InterruptedException e) {throw new RuntimeException(e);}}log.info("{} 執行~", Thread.currentThread().getName());//計數器減 1countDownLatch.countDown();},"t" + i).start();}}

3、通過Semaphore的方式

通過信號量控制,每個線程在開始執行前需要獲取一個許可,執行完畢后釋放下一個線程需要的許可。

    /*** 只讓第一個信號量有一個許可,另外兩個信號量沒有許可* 1、第一個線程獲取到許可,執行打印,然后釋放下一個信號量的許可* 2、第二個線程獲取到許可,執行打印,然后釋放下一個信號量的許可* 3、第三個線程獲取到許可,執行打印*/@Testvoid testMethod3(){int length = 3;List<Semaphore> semaphoreList = new ArrayList<>();for (int i = 1; i <= length; i++) {Semaphore semaphore = new Semaphore(i == 1 ? 1 : 0);semaphoreList.add(semaphore);}for (int j = 0; j < length; j++) {final int theadIndex = j;new Thread(() -> {try {//獲取許可semaphoreList.get(theadIndex).acquire();log.info("{} 執行~", Thread.currentThread().getName());} catch (InterruptedException e) {throw new RuntimeException(e);}finally {//釋放許可if (theadIndex != length - 1) {semaphoreList.get(theadIndex + 1).release();}}},"t" + (j + 1)).start();}}

4、CompletableFuture的方式

原理:異步任務鏈式調用
優勢:代碼簡潔,內置線程池管理

CompletableFuture.runAsync(() -> System.out.println("t1")).thenRun(() -> System.out.println("t2")).thenRun(() -> System.out.println("t3")).join();  // 阻塞等待全部完成

5、利用線程池

原理:所有任務提交到單線程隊列順序執行
優勢:自動管理線程生命周期
注意:實際是同一個線程執行所有任務

ExecutorService executor = Executors.newSingleThreadExecutor();
executor.submit(() -> System.out.println("t1"));
executor.submit(() -> System.out.println("t2"));
executor.submit(() -> System.out.println("t3"));
executor.shutdown();

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

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

相關文章

在 Vue 項目中關閉 ESLint 規則

在 Vue 2 項目中關閉 ESLint 規則有以下幾種方法&#xff0c;根據您的需求選擇合適的方式&#xff1a; 1. 完全禁用 ESLint 修改 vue.config.js&#xff08;推薦&#xff09; module.exports {// 關閉 ESLintlintOnSave: false }或修改 package.json {"scripts": {&…

電腦息屏工具,一鍵黑屏超方便

軟件介紹 今天為大家推薦一款實用的PC端屏幕管理工具——CloseDsp。這款"息屏小能手"能一鍵關閉顯示器&#xff0c;解決各種場景下的屏幕管理需求。 核心功能 CloseDsp最突出的特點是能瞬間關閉顯示器屏幕。只需點擊"關閉顯示器"按鈕&#xff0c;屏幕…

嵌入式調試LOG日志輸出(以STM32為例)

引言在嵌入式系統開發中&#xff0c;調試是貫穿整個生命周期的關鍵環節。與傳統PC端程序不同&#xff0c;嵌入式設備資源受限&#xff08;如內存、存儲、處理器性能&#xff09;&#xff0c;且運行環境復雜&#xff08;無顯示器、鍵盤&#xff09;&#xff0c;傳統的斷點調試或…

Zephyr的設備驅動模型

默認配置默認配置 boards/arm/nucleo_f401re/ ├── nucleo_f401re.dts ← 板卡設備樹主入口 ├── nucleo_f401re_defconfig ← 默認 Kconfig 配置 ├── board.cmake ← CMake 構建入口overlay1.新增加驅動需要修改對應板的設備樹文件&#xf…

Mysql字段沒有索引,通過where x = 3 for update是使用什么級別的鎖

沒有索引時&#xff0c;FOR UPDATE 會鎖住整個表 現在&#xff0c;你正在一本一本地翻看所有書&#xff0c;尋找“維修中”的書&#xff0c;并且你對管理員說&#xff1a;“在我清點和修改完之前&#xff0c;別人不能動這些書&#xff0c;也不能往這個范圍里加新書&#xff01;…

TCP-與-UDP-協議詳解:原理、區別與應用場景全解析

TCP 與 UDP 協議詳解&#xff1a;原理、區別與應用場景全解析 在日常使用網絡的過程中&#xff0c;我們經常聽到 TCP 和 UDP 這兩個詞。你打開網頁、發送消息、觀看視頻&#xff0c;背后都在使用 TCP 或 UDP 進行數據傳輸。那么這兩個協議到底是怎么工作的&#xff1f;它們之間…

GitHub信息收集

目錄 簡介 一、入門搜索技巧 1. 基本關鍵詞搜索 2. 文件類型限定搜索 3. 用戶/組織定向搜索 二、精準定位技巧 1. 組合搜索條件 2. 排除干擾結果 3. 路徑限定搜索 三、防御建議 四、法律與道德提醒 簡介 GitHub作為全球最大的代碼托管平臺&#xff0c;存儲著數十億…

由 DB_FILES 參數導致的 dg 服務器無法同步問題

由 DB_FILES 參數導致的 dg 服務器無法同步問題 用戶反映&#xff0c;dg 服務器數據從昨晚&#xff08;7月8日&#xff09;開始停止同步。 連接服務器發現沒有 mrp 進程&#xff0c;并且 OPEN_MODE 參數也不正確。具體情況如下所示&#xff1a; SQL> select process, status…

Go語言泛型-泛型對代碼結構的優化

在Go語言中,Go泛型-泛型對代碼結構的優化部分主要探討了泛型如何幫助我們優化代碼結構、減少重復代碼,并提高代碼的可維護性、可讀性和復用性。以下是詳細內容: 一、引言 Go 1.18 引入了泛型,極大地提高了語言的靈活性。泛型使得我們可以編寫更加通用、可復用且類型安全的…

【1-快速上手】

文章目錄前言簡介什么是 Konva&#xff1f;安裝 Konva概述它是如何工作的&#xff1f;基本形狀樣式事件拖放濾鏡動畫選擇器序列化與反序列化性能前言 結合項目實際業務需求&#xff0c;在 Fabric、Konva 等圖形化框架中&#xff0c;我選擇了性能表現好的 Konva。首先去學習官方…

【LeetCode】209. 長度最小的子數組(前綴和 + 二分)

【LeetCode】209. 長度最小的子數組&#xff08;前綴和 二分&#xff09;題目描述前綴和二分優化前綴和總結二分總結題目描述 題目鏈接&#xff1a;【LeetCode】209. 長度最小的子數組&#xff08;前綴和 二分&#xff09; 給定一個含有 n 個整數的數組和一個整數 target。…

文件系統----底層架構

當我們談到文件系統的時候&#xff0c;最重要的點在于&#xff1a;文件的內容與屬性是如何存儲在磁盤中的&#xff1f;以及操作系統是如何精準定位到這些文件內容的&#xff1f;在談及文件的內核前&#xff0c;我們先來了解一下儲存文件的硬件-----硬盤一.理解硬件首先我們來看…

小程序開發平臺,自主開發小程序源碼系統,多端適配,帶完整的部署教程

溫馨提示&#xff1a;文末有資源獲取方式全開源與自主開發源碼完全開放&#xff1a;開發者可自由修改前端界面、后端邏輯及數據庫結構&#xff0c;支持深度定制&#xff08;如調整用戶端交互流程、商家端管理功能等&#xff09;。技術棧透明&#xff1a;基于主流技術&#xff0…

stp拓撲變化分類

Max Age 20sHellotime 2sForward delay 153、拓撲改變需要多長時間1&#xff09;根橋故障&#xff1a;需要50秒&#xff08;Max age2個forwarding delay&#xff09;2&#xff09;非直連鏈路&#xff1a;非直連故障在穩定的STP網絡&#xff0c;非根橋會定期收到來自根橋的BPDU報…

一、深度學習——神經網絡

一、神經網絡 1.神經網絡定義&#xff1a;人工神經網絡&#xff08;Artificial Neural Network&#xff0c;ANN&#xff09;也簡稱為神經網絡&#xff08;NN&#xff09;&#xff0c;是一種模仿生物神經網絡結構和功能的計算模型。人腦可以看作是一個生物神經網絡&#xff0c;由…

【牛客算法】 小紅的奇偶抽取

文章目錄 一、題目介紹1.1 題目描述1.2 輸入描述1.3 輸出描述1.4 示例二、解題思路2.1 核心算法設計2.2 性能優化關鍵2.3 算法流程圖三、解法實現3.1 解法一:字符串分離法3.1.1 初級版本分析3.2 解法二:數學逐位構建法(推薦)3.2.1 優化版本分析四、總結與拓展4.1 關鍵優化技…

Maven 繼承:構建高效項目結構的利器

一、引言 Maven 是一個強大的項目管理工具&#xff0c;它通過標準化的項目結構和依賴管理極大地簡化了 Java 項目的開發流程。在 Maven 中&#xff0c;繼承是一種非常有用的功能&#xff0c;它允許我們創建一個父項目&#xff0c;其他子項目可以繼承這個父項目的配置信息&#…

Mysql組合索引的update在多種情況下的間隙鎖的范圍(簡單來說)

簡單來說&#xff0c;當 UPDATE 語句的 WHERE 條件使用了組合索引&#xff0c;并且需要鎖定不存在的“間隙”來防止幻讀時&#xff0c;就會產生間隙鎖。間隙鎖的范圍取決于 WHERE 條件如何利用組合索引&#xff0c;以及數據庫的隔離級別。 我們用圖書館的例子。比如&#xff1a…

什么是Apache Ignite的affinity(親和性)

在 Apache Ignite 中&#xff0c; affinity&#xff08;親和性&#xff09; 是一種用于控制數據分布和查詢性能的重要機制。它允許開發者指定數據如何在集群中的節點之間分布&#xff0c;從而優化數據訪問和查詢效率。以下是關于 affinity 的詳細解釋&#xff1a;數據親和性&a…

youtube圖論

dfs排序lifo & fifo存儲方式鄰接矩陣dijstra處理過的保存/更新&#xff0c;意味著一個節點避免了重復訪問bfs dfs