Java實現多線程的三種方式

Java 有三種方式實現多線程,繼承 Thread 類、實現 Runnable 接口、實現 Callable 接口。還有匿名內部類方式,Lambda 表達式方式簡化開發。

1、Thread

Thread 創建線程方式:創建線程類

  • start() 方法底層其實是給 CPU 注冊當前線程,并且觸發 run() 方法執行

  • 線程的啟動必須調用 start() 方法,如果線程直接調用 run() 方法,相當于變成了普通類的執行,此時主線程將只有執行該線程

  • 建議線程先創建子線程,主線程的任務放在之后,否則主線程(main)永遠是先執行完

Thread 構造器:

  • public Thread()

  • public Thread(String name)

public class p1 {public static void main(String[] args) {// 創建線程類方式Thread t1 = new MyThread();t1.start();}
}
class MyThread extends Thread{@Overridepublic void run() {for(int i = 0 ; i < 100 ; i++ ) {// 子線程輸出System.out.println(Thread.currentThread().getName() + "->" + i);}}
}

繼承 Thread 類的優缺點:

  • 優點:編碼簡單

  • 缺點:線程類已經繼承了 Thread 類無法繼承其他類了,功能不能通過繼承拓展(單繼承的局限性)

2、Runnable

Runnable 創建線程方式:創建線程類

Thread 的構造器:

  • public Thread(Runnable target)

  • public Thread(Runnable target, String name)

public class p2 {public static void main(String[] args) {Runnable target = new MyRunnable();Thread t1 = new Thread(target,"Runnable線程");t1.start();Thread t2 = new Thread(target);//Thread-0}
}public class MyRunnable implements Runnable{@Overridepublic void run() {for(int i = 0 ; i < 10 ; i++ ){System.out.println(Thread.currentThread().getName() + "->" + i);}}
}

Thread 類本身也是實現了 Runnable 接口,Thread 類中持有 Runnable 的屬性,執行線程 run 方法底層是調用 Runnable#run:

?public class Thread implements Runnable {private Runnable target;public void run() {if (target != null) {// 底層調用的是 Runnable 的 run 方法target.run();}}}

Runnable 方式的優缺點:

  • 缺點:代碼復雜一點。

  • 優點

    • 線程任務類只是實現了 Runnable 接口,可以繼續繼承其他類,避免了單繼承的局限性

    • 同一個線程任務對象可以被包裝成多個線程對象

    • 適合多個多個線程去共享同一個資源

    • 實現解耦操作,線程任務代碼可以被多個線程共享,線程任務代碼和線程獨立

    • 線程池可以放入實現 Runnable 或 Callable 線程任務對象

3、Callable

實現 Callable 接口:

  1. 定義一個線程任務類實現 Callable 接口,申明線程執行的結果類型

  2. 重寫線程任務類的 call 方法,這個方法可以直接返回執行的結果

  3. 創建一個 Callable 的線程任務對象

  4. 把 Callable 的線程任務對象包裝成一個未來任務對象

  5. 把未來任務對象包裝成線程對象

  6. 調用線程的 start() 方法啟動線程

public FutureTask(Callable<V> callable):未來任務對象,在線程執行完后得到線程的執行結果

  • FutureTask 就是 Runnable 對象,因為 Thread 類只能執行 Runnable 實例的任務對象,所以把 Callable 包裝成未來任務對象

public V get():同步等待 task 執行完畢的結果,如果在線程中獲取另一個線程執行結果,會阻塞等待,用于線程同步

  • get() 線程會阻塞等待任務執行完成

  • run() 執行完后會把結果設置到 FutureTask 的一個成員變量,get() 線程可以獲取到該變量的值

public class p3 {public static void main(String[] args) {Callable<String> call = new MyCallable();FutureTask<String> task = new FutureTask<>(call);Thread t1 = new Thread(task);t1.start();try {// 獲取call方法返回的結果(正常/異常結果)String s = task.get(); System.out.println(s);}  catch (Exception e) {e.printStackTrace();}}public class MyCallable implements Callable<String> {@Overridepublic String call() throws Exception {return Thread.currentThread().getName() + "->" + "MyCallable String";}
}

優缺點:

  • 優點:同 Runnable,并且能得到線程執行的結果

  • 缺點:編碼復雜

4、匿名內部類方式、Lambda 表達式方式
public class p1 {public static void main(String[] args) {// 匿名內部類方式Thread t1 = new Thread(new Runnable() {@Overridepublic void run() {System.out.println("t1 線程執行中");}});t1.start();// Lambda 表達式創建匿名內部類的線程對象Thread t2= new Thread(() -> {System.out.println("t2 線程執行中");});t2.start();}
}    

使用匿名內部類的方式可以方便地定義并實例化線程對象,并實現線程的執行邏輯。它對于一些簡單的線程任務可以簡潔地表達,但對于復雜的線程邏輯,建議使用具名的內部類或者單獨定義一個類來實現Runnable接口

使用 lambda 表達式代替了匿名內部類,使得代碼更加簡潔。適用于只包含一個抽象方法的接口,例如 Runnable 接口和 Callable 接口。對于其他接口,如果包含多個抽象方法,就無法使用 lambda 表達式來創建匿名內部類。

借鑒:https://github.com/Seazean/JavaNote/blob/main/Prog.md

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

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

相關文章

關于IDEA中maven的作用以及如何配置MAVEN

關于IDEA中maven的作用以及如何配置MAVEN 1、Maven是什么2、Idea中對于Maven的配置3、下載依賴時&#xff0c;Idea下方的顯示3.1、Maven中央倉庫的下載顯示界面3.2、阿里云倉庫的下載顯示界面 4、Maven在Idea中的使用4.1、clean4.2、validate4.3、compile4.4、test&#xff08;…

智能優化算法應用:基于人工蜂群算法3D無線傳感器網絡(WSN)覆蓋優化 - 附代碼

智能優化算法應用&#xff1a;基于人工蜂群算法3D無線傳感器網絡(WSN)覆蓋優化 - 附代碼 文章目錄 智能優化算法應用&#xff1a;基于人工蜂群算法3D無線傳感器網絡(WSN)覆蓋優化 - 附代碼1.無線傳感網絡節點模型2.覆蓋數學模型及分析3.人工蜂群算法4.實驗參數設定5.算法結果6.…

java智能異常處理

標題&#xff1a;優雅處理異常&#xff1a;Java智能異常處理的最佳實踐 摘要&#xff1a;在軟件開發中&#xff0c;異常處理是一項至關重要的任務。本文將介紹Java中的智能異常處理技術&#xff0c;通過合理的異常處理規范和最佳實踐&#xff0c;幫助開發者優雅地處理異常情況…

從零構建屬于自己的GPT系列5:模型部署1(文本生成函數解讀、模型本地化部署、文本生成文本網頁展示、代碼逐行解讀)

&#x1f6a9;&#x1f6a9;&#x1f6a9;Hugging Face 實戰系列 總目錄 有任何問題歡迎在下面留言 本篇文章的代碼運行界面均在PyCharm中進行 本篇文章配套的代碼資源已經上傳 從零構建屬于自己的GPT系列1&#xff1a;數據預處理 從零構建屬于自己的GPT系列2&#xff1a;模型訓…

2023年國賽高教杯數學建模A題定日鏡場的優化設計解題全過程文檔及程序

2023年國賽高教杯數學建模 A題 定日鏡場的優化設計 原題再現 構建以新能源為主體的新型電力系統&#xff0c;是我國實現“碳達峰”“碳中和”目標的一項重要措施。塔式太陽能光熱發電是一種低碳環保的新型清潔能源技術[1]。 ??定日鏡是塔式太陽能光熱發電站&#xff08;以下…

ES6-import后是否有{}的區別

在ES6中&#xff0c;import語句用于導入其他模塊中的變量、函數、類等。在使用import語句時&#xff0c;可以選擇是否使用花括號{}來包裹導入的內容&#xff0c;這會影響導入的內容的使用方式。 1.使用花括號{}&#xff1a; 當使用花括號{}時&#xff0c;表示只導入指定的變量…

【Fastadmin】根據Fieldlist鍵值組件做一個等級配置的完整示例

目錄 1.效果展示&#xff1a; ?編輯 2.建表&#xff1a; 3.html頁面 4.controller控制器 5.js 6.model 1.效果展示&#xff1a; 2.建表&#xff1a; 表名&#xff1a;fa_xxfb_config /*Navicat Premium Data TransferSource Server : rootSource Server Type …

深入Docker命令行:探索常用命令和實用技巧

Docker命令行界面是每個容器開發者的得力工具。在這篇文章中&#xff0c;將深入探討一系列常用的Docker命令&#xff0c;以及一些實用技巧&#xff0c;通過更豐富的示例代碼&#xff0c;幫助大家更全面地理解和運用Docker命令行工具。 1. Docker基本命令 1.1 鏡像操作 深入了…

用 CSS 寫一個漸變色邊框的輸入框

Using_CSS_gradients MDN 多漸變色輸入框&#xff0c;群友問了下&#xff0c;就試著寫了下&#xff0c;看了看 css 漸變色 MDN 文檔&#xff0c;其實很簡單&#xff0c;代碼記錄下&#xff1a; <!DOCTYPE html> <html lang"en"><head><meta ch…

使用FFMPEG轉碼,轉單聲道,轉標準WAV,轉PCM

本文為使用FFMPEG命令行的方式處理音頻&#xff0c;來獲取想要得到的音頻文件。 零、使用命令行查看編碼封裝信息 格式&#xff1a;ffprobe.exe -show_format inputfile 例子&#xff1a;ffprobe.exe -show_format .\stereo_44_16bit.wav 運行結果為下圖&#xff1a; 如圖可…

C# Channel實現線程間通信

C# Channel實現線程間通信 同步方式實現&#xff1a; using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Channels; using System.Threading.T…

【JavaFX】實現計算器小程序

下面是一個簡單的JavaFX計算器示例: import javafx.application.Application; import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.geometry.Insets; import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.…

西南科技大學數字電子技術實驗四(基本觸發器邏輯功能測試及FPGA的實現)預習報告

一、計算/設計過程 說明:本實驗是驗證性實驗,計算預測驗證結果。是設計性實驗一定要從系統指標計算出元件參數過程,越詳細越好。用公式輸入法完成相關公式內容,不得貼手寫圖片。(注意:從抽象公式直接得出結果,不得分,頁數可根據內容調整) (1)D觸發器 特征方程: Q…

往adobe illustrator中添加latex字體

找到如下字體所在路徑 /path/to/miktex/type1\public\amsfonts\cm然后copy相應的字體文件 cmmi10.pfb將相應的pfb文件復制到Adobe illustrator字體文件夾: /path/to/illustrator/Support Files/Required/Fonts然后重啟即可。

ChatGPT/GPT4應用:文本、論文、編程、繪圖等,提高工作效率及科研項目開發能力

2023年隨著OpenAI開發者大會的召開&#xff0c;最重磅更新當屬GPTs&#xff0c;多模態API&#xff0c;未來自定義專屬的GPT。微軟創始人比爾蓋茨稱ChatGPT的出現有著重大歷史意義&#xff0c;不亞于互聯網和個人電腦的問世。360創始人周鴻祎認為未來各行各業如果不能搭上這班車…

排序-選擇排序與堆排序

文章目錄 一、選擇排序二、堆排序三、時間復雜度四、穩定性 一、選擇排序 思想&#xff1a; 將數組第一個元素作為min&#xff0c;然后進行遍歷與其他元素對比&#xff0c;找到比min小的數就進行交換&#xff0c;直到最后一個元素就停止&#xff0c;然后再將第二個元素min&…

【單調棧】【二分查找】LeetCode: 2454.下一個更大元素 IV

作者推薦 【動態規劃】【廣度優先】LeetCode2258:逃離火災 本文涉及的基礎知識點 二分查找算法合集 單調棧 題目 給你一個下標從 0 開始的非負整數數組 nums 。對于 nums 中每一個整數&#xff0c;你必須找到對應元素的 第二大 整數。 如果 nums[j] 滿足以下條件&#xff…

音視頻技術開發周刊 | 323

每周一期&#xff0c;縱覽音視頻技術領域的干貨。 新聞投稿&#xff1a;contributelivevideostack.com。 Meta牽頭組建開源「AI復仇者聯盟」&#xff0c;AMD等盟友800億美元力戰OpenAI英偉達 超過50家科技大廠名校和機構&#xff0c;共同成立了全新的人工智能聯盟。以開源為旗號…

RocketMQ的架構是什么樣的?

RocketMQ&#xff0c;作為一款強大的分布式消息中間件&#xff0c;廣泛應用于各種大規模分布式系統中&#xff0c;為異步消息通信提供了可靠的解決方案。本文將深入探討RocketMQ的核心組件&#xff0c;包括Producer、Broker、Consumer和NameServer&#xff0c;以及它們在整個架…

高中物理電學總結之穩恒電流篇

高中物理電學總結之穩恒電流篇 電流電流的定義對電流的微觀分析 電阻歐姆定律電阻的串并聯電阻定律 電源的電動勢電源電動勢 閉合電路歐姆定律閉合電路閉合電路歐姆定律 電流做功與焦耳定律電流做功電功率焦耳定律電源效率 電表改裝 電流 電流的定義 電解質溶液中的自由電荷是…