JAVA基礎|多線程

什么是線程?

線程(Thread)是一個程序內部的一條執行流程。

多線程是什么?

多線程是指從軟硬件上實現的多條執行流程的技術(多條線程由CPU負責調度執行)

一. 如何在程序中創建出多條線程?

Java是通過java.lang.Thread類的對象來代表線程的。

1. 多線程的創建方式一:繼承Thread類

  1. 定義一個子類MyThread繼承線程類java.lang.Thread,重寫run()方法
  2. 創建MyThread類的對象
  3. 調用線程對象的start()方法啟動線程(啟動后還是執行run方法的)

ThreadTest1.java:

public class ThreadTest {// main方法是由一條默認的主線程負責執行的。public static void main(String[] args) {// 3. 創建Mythread線程類的對象代表一個線程Thread t = new MyThread();// 4. 啟動線程(自動執行run方法的)t.start();  // main線程 t線程for (int i = 1; i <= 5; i++) {System.out.println("主線程main輸出: " + i);}}
}

MyThread.java:

//1. 讓子類繼承Thread線程類
public class MyThread extends Thread{// 2. 必須重寫Thread類的run方法@Overridepublic void run() {for (int i = 1; i <= 5; i++) {System.out.println("子線程MyThread線程輸出: " + i);}}
}

方式一的優缺點:

  • 優點:編碼簡單
  • 缺點:線程類已經繼承Thread,無法繼承其他類,不利于功能的擴展。

2. 多線程的創建方式二:實現Runnable接口

  1. 定義一個線程任務類MyRunnable實現Runnable接口,重寫run()方法
  2. 創建MyRunnable任務對象
  3. 把MyRunnable任務對象交給Thread處理(因為任務對象不是線程對象,不能調用start方法,所以要將他封裝為線程對象)使用Thread自帶的構造器來做。
  4. 調用線程對象的start()方法啟動線程

ThreadTest.java

public class ThreadTest {public static void main(String[] args) {// 3. 創建任務對象Runnable target = new MyRunnable();// 4. 把任務對象交給一個線程對象處理// public Thread(Runnable target)new Thread(target).start();for (int i = 0; i <= 5; i++) {System.out.println("主線程main輸出 ===> " + i);}}
}

MyRunnable.java:?

// 1. 定義一個任務類,實現Runnable接口
public class MyRunnable implements Runnable {// 2. 重寫runnable的run方法@Overridepublic void run() {//線程要執行的任務for (int i = 0; i <=5; i++) {System.out.println("子線程輸出 ===》" + i);}}
}

?方式二的優缺點:

  • 優點:任務類只是實現接口,可以繼續繼承其他類,實現其他接口,擴展性能
  • 缺點:需要多創建一個Runnable對象(其實也不算啥缺點。。)

方法二的匿名內部類寫法:

  1. 可以創建Runnable的匿名內部類對象
  2. 再交給Thread線程對象
  3. 再調用線程對象的start()啟動線程?
public class ThreadTest2_2 {public static void main(String[] args) {// 1. 直接創建Runnable接口的匿名內部類形式(任務對象)Runnable target = new Runnable() {@Overridepublic void run() {for (int i = 0; i <= 5; i++) {System.out.println("子線程1輸出: " + i);}}};new Thread(target).start();for (int i = 0; i <= 5; i++) {System.out.println("主線程main輸出: " + i);}}
}

簡化:

//簡化形式1: new Thread(new Runnable() {@Overridepublic void run() {for (int i = 0; i <= 5; i++) {System.out.println("子線程1輸出: " + i);}}}).start();//簡化形式2:new Thread(() -> {for (int i = 0; i <= 5; i++) {System.out.println("子線程1輸出: " + i);}}).start();

3. 多線程的創建方式三:實現Callable接口,利用FutureTask類

前兩種線程創建方式都存在的一個問題

假如線程執行完畢后有一些數據需要返回,他們重寫的run方法均不能直接返回結果。

怎么解決這個這個問題呢?

  • JDK 5.0 提供了Callable接口和FutureTask類來實現(多線程的第三種創建方式)
  • 這種方式最大的優點:可以返回線程執行完畢后的結果。

創建方法

  1. 創建任務對象
  2. 定義一個類實現Callable接口,重寫call方法,封裝要做的事情和要返回的數據
  3. 把Callable類型的對象封裝成FutureTask(線程任務對象)
  4. 把線程任務對象交給Thread對象
  5. 調用Thread對象的start方法啟動線程
  6. 線程執行完畢后,通過FutureTask對象的get方法去獲取線程任務執行的結果

ThreadTest.java:

import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;public class ThreadTest3 {public static void main(String[] args) throws Exception {// 3. 創建一個Callable的對象Callable<String> call = new MyCallable(100);// 4. 把Callable的對象封裝成一個FutureTask對象(任務對象)// 未來任務對象的作用?// 1. 是一個任務對象,實現了Runnable對象// 2. 可以在線程執行完畢之后,用未來任務對象調用get方法獲取線程執行完畢后的結果FutureTask<String> f1 = new FutureTask<>(call);// 5. 把任務對象交給一個Thread對象new Thread(f1).start();Callable<String> call2 = new MyCallable(100);FutureTask<String> f2 = new FutureTask<>(call2);new Thread(f2).start();// 6. 獲取線程執行完畢后返回的結果// 注意:如果執行到這,假如上面的線程還沒有執行完畢// 這里的代碼會暫停,等待上面線程執行完畢后才會獲取結果String rs = f1.get();System.out.println(rs);String rs2 = f2.get();System.out.println(rs2);T}
}

MyCallable.java:

import java.util.concurrent.Callable;// 1. 實現Callable接口
public class MyCallable implements Callable<String> {private int n;public MyCallable(int n) {this.n = n;}// 2. 重寫call方法@Overridepublic String call() throws Exception {// 描述線程的任務,返回線程執行返回后的結果// 需求: 求1-n的和返回int sum = 0;for (int i = 0; i <= n; i++) {sum += i;}return "線程求出了1-" + n + "的和是:" + sum;}
}

?方式三的優缺點:

  • 優點:線程任務類只是實現接口,可以繼續繼承類和實現接口,擴展性強;可以在線程執行完畢后去獲取線程執行的結果
  • 缺點:編碼復雜一點

二. 多線程的注意事項

  1. 啟動線程必須是調用start方法,不是調用run方法:使用run的話相當于調用了MyThread對象中的run方法,這樣就仍然是單線程。
  2. 不要把主線程任務放在啟動子線程之前:這樣的話主線程一直是先跑完的,相當于是一個單線程的效果了。

三. Thread的常用方法

?獲取當前線程的名字,設置線程名字:

ThreadTest.java:

public class ThreadTest {public static void main(String[] args) {Thread t1 = new MyThread("1號線程");/*t1.setName("1號線程");*/t1.start();System.out.println(t1.getName());   //Thread-0Thread t2 = new MyThread("2號線程");/*t2.setName("2號線程");*/t2.start();System.out.println(t2.getName());   //Thread-1//主線程對象的名字//哪個線程執行他,他就會得到哪個線程對象Thread m = Thread.currentThread();System.out.println(m.getName());for (int i = 0; i <= 5; i++) {System.out.println("main線程輸出: " + i);}}
}

MyThread.java:

public class MyThread extends Thread {public MyThread(String name) {super(name);    //為當前線程設置名字}@Overridepublic void run() {Thread t = Thread.currentThread();for (int i = 0; i <= 3; i++) {System.out.println(t.getName()+ "輸出: " + i);}}
}

sleep,join方法

public class ThreadTest2 {public static void main(String[] args) throws Exception{for (int i = 0; i <= 5; i++) {System.out.println(i);// 休眠5sif (i ==3) {//會讓當前執行的線程暫停5秒,再繼續執行//項目經歷讓我加上這行代碼,如果用戶交錢了,我就注釋掉! 「Doge」Thread.sleep(5000);}}// join方法作用:讓當前調用這個方法的線程先執行完Thread t1 = new MyThread("1號線程");t1.start();t1.join();Thread t2 = new MyThread("2號線程");t2.start();t2.join();Thread t3 = new MyThread("3號線程");t3.start();t3.join();}
}

四. 線程安全問題

什么是線程安全問題?

多個線程,同時操作同一個共享資源的時候,可能會出現業務安全問題。

用程序模擬線程安全問題

1

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

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

相關文章

新接手業務的線上Bug特別多怎么辦?

文章目錄 接手&#xff1a;保證質量順利過渡緊急質量審計臨時增加測試頻次灰度發布加強監控與預警建立快速反饋機制 打補丁&#xff1a;針對性解決質量問題Bug 分析與分類測試策略優化環境一致性 搞基建&#xff1a;全流程質量控制需求分析與評審設計階段的評審與驗證代碼質量控…

Windows10系統中安裝與配置PyTorch(無GPU版本)

文章目錄 1. 什么是PyTorch2. PyTorch的安裝與配置&#xff08;無GPU&#xff09;2.1 創建環境2.2 安裝pytorch庫&#xff08;無GPU&#xff09;2.3 驗證安裝結果 1. 什么是PyTorch PyTorch 是一種用于構建深度學習模型且功能完備的開源框架&#xff0c;通常用于處理圖像識別和…

JVM學習-自定義類加載器

為什么要自定義類加載器 隔離加載類 在某些框架內進行中間件與應用的模塊隔離&#xff0c;把類加載到不同的環境&#xff0c;如Tomcat這類Web應用服務器&#xff0c;內部自定義了好幾種類加載器&#xff0c;用于隔離同一個Web應用服務器上的不同應用程序 修改類加載的方式 …

OpenCV 的幾種查找圖像中輪廓邊緣的方法

原始圖片&#xff1a; 1、Sobel() Sobel 算子結合了高斯平滑和微分&#xff0c;用于計算圖像的梯度&#xff0c;從而突出顯示邊緣。 import cv2# 讀取圖像 image cv2.imread(image.png, cv2.IMREAD_GRAYSCALE)# 使用 Sobel 算子查找水平和垂直邊緣 sobel_x cv2.Sobel(image…

建筑企業有閑置資質怎么辦?

如果建筑企業擁有閑置資質&#xff0c;可以考慮以下幾種方式來充分利用這些資質&#xff1a; 1. 租賃或轉讓資質&#xff1a; 將閑置的建筑資質租賃給其他企業或個人使用&#xff0c;或者通過轉讓的方式將資質出售給有需要的企業或個人。 2. 提供咨詢服務&#xff1a; 利用建…

git分布式版本控制系統(四)

目前世界上最先進的分布式版本控制系統 官方網址&#xff1a;https://git-scm.com 學習目標&#xff1a; 1 了解 git 前世今生 2 掌握 git 基礎概念、基礎操作 3 各種 git 問題處理 4 互聯網常用 gitflow(工作流程規范) 5 git 代碼提交規范 6 git 分支管理及命名規范 常見問…

OneForall工具的下載安裝和使用(Windows和Linux)

目錄 OneForall的介紹 OneForall的下載 OneForall的安裝 安裝要求 安裝步驟&#xff08;git 版&#xff09; 安裝&#xff08;kali&#xff09; OneForall的使用命令 在Windows 在Linux&#xff08;kali&#xff09; OneForall的結果說明 免責聲明 本文所提供的文字和…

車輛前向碰撞預警系統性能要求和測試規程

前言 本文整理《GB/T 33577-2017 智能運輸系統-車輛前向碰撞預警系統性能要求和測試規程》國標文件關鍵信息,FCW系統性能和測試右給深層次的認識。 術語和定義 車輛前向碰撞預警系統 forward vehicle collision warning system自車 subject vehicle(SV)目標車輛 target ve…

【Linux】查找和壓縮

一、文件查找 1、命令查找 which 2、文件查找、依賴數據庫 locate 3、文件查找 find 語法&#xff1a;find [path] [options] [expression] [action] ①按文件名 -name按名 -iname可不區分大小寫 ②按文件大小 5M&#xff1a;5M以上文件 5M&#xff1a;5M文件 -…

高中數學:解三角形相關公式總結及用法總結

一、正弦定理 二、余弦定理 三、三角形面積公式 由正弦定理&#xff0c;可以推出三角形的面積公式&#xff1a; S*ab*sinC S*ac*sinB S*bc*sinA 四、使用方法總結 五、練習 例題1 解析 對條件等式進行變形&#xff0c;結合余弦定理&#xff0c;求出∠A的度數&#xff0c;從而…

【面經分享-CPP篇】[建議收藏!!] C++基礎20問-01

&#x1f36d; 大家好這里是清隆學長 &#xff0c;一枚熱愛算法的程序員 ? 本系列打算持續跟新c面試基礎 &#x1f44f; 感謝大家的訂閱? 和 喜歡&#x1f497; 文章目錄 1.題目&#xff1a;解釋C中的RAII機制。2.題目&#xff1a;解釋C中的智能指針及其類型。3.題目&#xf…

從內存到sql的upsert

業務的upsert ? 在寫業務時&#xff0c;大家一開始都會以順序流程的方式開始著手寫代碼&#xff0c;CR時再看代碼&#xff0c;會有不一樣的感覺。 1. 需求描述 ? 現有一張數據庫表&#xff0c;表字段結構如下&#xff1a; 字段名稱類型描述uuidstring數據的唯一鍵datastrin…

代碼隨想錄算法訓練營第四十六天|KM52. 攜帶研究材料、518. 零錢兌換 II、377. 組合總和 Ⅳ

代碼隨想錄算法訓練營第四十六天 KM52. 攜帶研究材料 題目鏈接&#xff1a;KM52. 攜帶研究材料 確定dp數組以及下標的含義&#xff1a;j的含義是當前背包的最大容量&#xff0c;dp[j]背包內物品的總價值確定遞推公式&#xff1a;背包最大容量固定為j&#xff0c;每個循環嘗試…

Nginx01-HTTP簡介與Nginx簡介(安裝、命令介紹、目錄介紹、配置文件介紹)

目錄 HTTP簡介HTTP原理查看訪問網站的詳細流程curl -vwget --debug 查看網站訪問量HTTP協議版本HTTP協議交互HTTP 請求請求報文起始行請求頭 HTTP響應響應報文起始行響應頭 Nginx常見的Web服務常見網站服務 安裝NginxNginx目錄結構Nginx啟動管理Nginx常用命令 Nginx配置文件主配…

國內外主流大模型語言技術大比拼

國內外主流大模型語言技術對比 2024 自2017年起&#xff0c;美國深度布局人工智能&#xff0c;全面融入經濟、文化與社會。至2023年&#xff0c;中國憑借自研技術平臺嶄露頭角&#xff0c;ChatGPT及其技術成國家戰略焦點&#xff0c;引領未來科技浪潮。中美競逐&#xff0c;人工…

Milvus向量數據庫:開啟向量搜索新紀元

Milvus向量數據庫&#xff1a;開啟向量搜索新紀元 隨著人工智能和機器學習技術的飛速發展&#xff0c;向量數據在各個領域的應用越來越廣泛&#xff0c;如推薦系統、自然語言處理、計算機視覺等。在這樣的背景下&#xff0c;如何高效地存儲、查詢和管理向量數據成為了一個重要的…

香橙派 AI pro:AI 加速初體驗

香橙派 AI pro&#xff1a;AI 加速初體驗 在AI領域&#xff0c;不斷涌現的硬件產品為開發者提供了前所未有的便利和可能性。今天&#xff0c;我要介紹的這款產品——香橙派 AIpro&#xff0c;就是其中的佼佼者。在昇騰 AI 芯片的加持下&#xff0c;這款開發板有著出色的算力。…

961題庫 北航計算機 操作系統 附答案 選擇題形式

有題目和答案&#xff0c;沒有解析&#xff0c;不懂的題問大模型即可&#xff0c;無償分享。 第1組 習題 計算機系統的組成包括&#xff08; &#xff09; A、程序和數據 B、處理器和內存 C、計算機硬件和計算機軟件 D、處理器、存儲器和外圍設備 財務軟件是一種&#xff…

【Qt 學習筆記】Qt窗口 | 對話框 | Qt對話框的分類及介紹

博客主頁&#xff1a;Duck Bro 博客主頁系列專欄&#xff1a;Qt 專欄關注博主&#xff0c;后期持續更新系列文章如果有錯誤感謝請大家批評指出&#xff0c;及時修改感謝大家點贊&#x1f44d;收藏?評論? Qt窗口 | 對話框 | 模態對話框 文章編號&#xff1a;Qt 學習筆記 / 51…

Java反序列化漏洞與URLDNS利用鏈分析

前言 前面學習過 Java 反序列化漏洞的部分知識&#xff0c;總結過幾篇文章&#xff1a; 文章發布日期內容概括《滲透測試-JBoss 5.x/6.x反序列化漏洞》2020-07-08JBoss 反序列化漏洞 CVE-2017-12149 的簡單復現&#xff0c;使用了 ysoserial 和 CC5 鏈&#xff0c;未分析漏洞…