多線程(二) ~ 線程核心屬性與狀態

文章目錄

  • 一. 線程創建(start)
    • (一)繼承Thread類,重寫run
    • (二)繼承Runnable類,重寫run
    • (三)Thread匿名內部類重寫
    • (四)Runnable匿名內部類重寫
    • (五)lambda表達式
  • 二. 線程的關鍵屬性
    • (一)線程名稱
    • (二)線程是否為后臺線程
      • 1. 前臺線程
      • 2. 后臺線程
      • 3. 查看是否是后臺線程(isDaemon)
      • 4. 設置后臺線程(setDaemon)代碼及效果圖
    • (三)線程是否存活
      • 1. 是否存活isAlive
      • 2. 代碼及效果圖
  • 三. 線程終止(interrupt)
    • (一)Java提供的API
      • 1. 用法
      • 2. 代碼及效果圖
    • (二)手動設置條件
      • 1. 用法
      • 2. 代碼及其效果圖
  • 四. 線程等待(join)
    • (一)定義
    • (二)代碼及其效果圖
  • 五. 獲取線程引用(currentThread)
    • (一)用法
    • (二)代碼及其效果圖
  • 六. 線程休眠(sleep)
    • (一)定義
    • (二)代碼
  • 七. 線程狀態
    • (一)NEW
      • 1. 定義
      • 2. 代碼及其效果圖
    • (二)TERMINATED
      • 1. 定義
      • 2. 代碼及其效果圖
    • (三)RUNNABLE
      • 1. 定義
      • 2. 代碼及其效果圖
    • (四)TIMED_WAITING
      • 1. 定義
      • 2. 代碼及其效果圖
    • (五)WAITING
      • 1. 定義
      • 2. 代碼及其效果圖
    • (六)BLOCKED&LOCK
      • (①)
      • (②)
      • (③)

一. 線程創建(start)

(一)繼承Thread類,重寫run

class MyThread extends Thread {@Overridepublic void run() {while (true) {System.out.println("Thread!!!");try {Thread.sleep(100);} catch (InterruptedException e) {throw new RuntimeException(e);}}}
}public class demo1 {public static void main(String[] args) throws InterruptedException {Thread thread = new MyThread();thread.start();while (true) {System.out.println("main!!!");Thread.sleep(100);}}
}

(二)繼承Runnable類,重寫run

class MyRunnable implements Runnable {@Overridepublic void run() {while (true) {System.out.println("Thread!");}}
}public class demo2 {public static void main(String[] args) {MyRunnable runnable = new MyRunnable();Thread thread = new Thread(runnable);thread.start();while (true) {System.out.println("main!");}}
}

(三)Thread匿名內部類重寫

package demo_thread;/*** Created with IntelliJ IDEA.* Description:* User: 32309* Date: 2025-07-11* Time: 20:06*/
public class demo3 {public static void main(String[] args) throws InterruptedException {Thread thread = new Thread() {@Overridepublic void run() {while (true) {System.out.println("Thread~~");try {Thread.sleep(0);} catch (InterruptedException e) {throw new RuntimeException(e);}}}};thread.start();while (true) {System.out.println("main~~");Thread.sleep(0);}}
}

(四)Runnable匿名內部類重寫

package demo_thread;/*** Created with IntelliJ IDEA.* Description:* User: 32309* Date: 2025-07-11* Time: 20:14*/
public class demo4 {public static void main(String[] args) throws InterruptedException {Runnable runnable = new Runnable() {@Overridepublic void run() {while (true) {System.out.println("thread~");try {Thread.sleep(100);} catch (InterruptedException e) {throw new RuntimeException(e);}}}};Thread thread = new Thread(runnable);thread.start();while (true) {System.out.println("main~");Thread.sleep(100);}}
}

(五)lambda表達式

public class demo5 {public static void main(String[] args) throws InterruptedException {Thread thread = new Thread(() -> {while (true) {System.out.println("thread!");try {Thread.sleep(10);} catch (InterruptedException e) {throw new RuntimeException(e);}}},"阿然");thread.start();while (true) {System.out.println("main!");Thread.sleep(10);}}
}

二. 線程的關鍵屬性

(一)線程名稱

線程名字,我們可以通過setName方法來設置線程的名字,方便后期調試
通過getName方法可以獲取線程名稱
在這里插入圖片描述

(二)線程是否為后臺線程

1. 前臺線程

當前臺線程還在運行時,即使其他所有線程都運行完,進程也不停止,要等待前臺線程結束,進程才結束

2. 后臺線程

當所有前臺線程運行完畢時,即使后臺線程還有任務沒有完成,也會終止進程

3. 查看是否是后臺線程(isDaemon)

是否是后臺線程通過isDeamon方法來查看
Java中線程創建時默認是前臺線程

4. 設置后臺線程(setDaemon)代碼及效果圖

public class demo7 {public static void main(String[] args) throws InterruptedException {Thread thread = new Thread(() -> {while (true) {System.out.println("thread~~~");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}},"thread");thread.setDaemon(true);thread.start();System.out.println(thread.isDaemon());for (int i = 0; i < 1   ; i++) {System.out.println("main");Thread.sleep(1000);}}
}

在這里插入圖片描述

(三)線程是否存活

1. 是否存活isAlive

Java中Thread對象與CPU內核中的線程是一一對應的,但是有可能出現內核的線程已經摧毀了,而Thread對象還存在的情況
可以使用isAlive方法來查看線程是否存活

2. 代碼及效果圖

package demo_thread;/*** Created with IntelliJ IDEA.* Description:* User: 32309* Date: 2025-07-11* Time: 20:38*/
public class demo8 {public static void main(String[] args) throws InterruptedException {Thread thread = new Thread(() -> {for (int i = 0; i < 3; i++) {System.out.println("thread!");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}});thread.start();while (true) {System.out.println(thread.isAlive());Thread.sleep(1000);}}
}

在這里插入圖片描述

三. 線程終止(interrupt)

(一)Java提供的API

1. 用法

1.Java中提供了控制線程結束的方法interrupted與isInterrupted
2. isInterrupted默認是false,在循環中取反使用來運行線程任務
3. 調用interrupt讓isInterrupted置為true
4. 需要注意的是sleep休眠函數會使isInterrupted再次置為false

2. 代碼及效果圖

package demo_thread;/*** Created with IntelliJ IDEA.* Description:* User: 32309* Date: 2025-07-11* Time: 20:52*/
public class demo10_interrupt {public static void main(String[] args) throws InterruptedException {Thread thread = new Thread(() -> {while (!Thread.currentThread().isInterrupted()) {System.out.println(Thread.currentThread().getName());try {Thread.sleep(1000);} catch (InterruptedException e) {//throw new RuntimeException(e);break;}}System.out.println("進程結束");},"thread");thread.start();Thread.sleep(3000);System.out.println("main嘗試終止");thread.interrupt();}
}

(二)手動設置條件

1. 用法

1. 手動設置循環關閉條件時,布爾條件需要是成員變量
2. 如果是局部變量那么布爾條件則不能改變,這樣達不到關閉循環從而關閉線程的效果
3. 這是因為每次線程調度切換回該線程時,會從重新棧當中調取變量,如果局部變量則存在銷毀可能,無法調取

2. 代碼及其效果圖

package demo_thread;/*** Created with IntelliJ IDEA.* Description:* User: 32309* Date: 2025-07-11* Time: 20:47*/
public class demo9 {private static boolean isFinish = false;public static void main(String[] args) throws InterruptedException {Thread thread = new Thread(() -> {while (!isFinish) {System.out.println("thread~~~");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}System.out.println("進程結束");},"thread");thread.start();for (int i = 0; i < 3; i++) {Thread.sleep(1000);}System.out.println("嘗試終止進程翁");isFinish = true;}
}

在這里插入圖片描述

四. 線程等待(join)

(一)定義

1.Java中線程等待函數時join
2. 線程1調用join,線程1就是被等待的線程,要等到線程1結束后才能結束進程
3. join可以設置等待時間,在設定的等待時間結束后,不論線程1是否完成任務,都不再等待,結束進程
4. join會拋出一個InterruptedException異常

(二)代碼及其效果圖

package demo_thread;/*** Created with IntelliJ IDEA.* Description:* User: 32309* Date: 2025-07-12* Time: 20:08*/
public class demo11_join {public static void main(String[] args) throws InterruptedException {Thread thread = new Thread(() -> {for (int i = 0; i < 3; i++) {System.out.println("thread ~");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}System.out.println("thread 線程結束!");});thread.start();thread.join(4000);System.out.println("main 線程結束!");}
}

在這里插入圖片描述

五. 獲取線程引用(currentThread)

(一)用法

  1. Java中Thread封裝了獲取當前線程的API,即currentThread方法
  2. currentThread方法是靜態方法,可以直接用類名Thread調用

(二)代碼及其效果圖

package demo_thread;/*** Created with IntelliJ IDEA.* Description:* User: 32309* Date: 2025-07-13* Time: 21:46*/
public class demo_currentThread {public static void main(String[] args) {Thread main = Thread.currentThread();Thread thread = new Thread(() -> {for (int i = 0; i < 3; i++) {System.out.println("thread@");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}System.out.println("thread 線程結束");});thread.start();for (int i = 0; i < 5; i++) {System.out.println("main@");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}System.out.println("main 結束");}
}

在這里插入圖片描述

六. 線程休眠(sleep)

(一)定義

1 Java中休眠方法是sleep
2. sleep方法是靜態方法,可以直接用Thread調用
3. 調用sleep方法會拋出InterruptedException異常

(二)代碼

                try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}

七. 線程狀態

(一)NEW

1. 定義

線程還未創建的狀態,沒調用start

2. 代碼及其效果圖

package demo_thread;/*** Created with IntelliJ IDEA.* Description:* User: 32309* Date: 2025-07-12* Time: 20:18*/
public class demo12_new {public static void main(String[] args) {Thread thread = new Thread();System.out.println(thread.getState());}
}

在這里插入圖片描述

(二)TERMINATED

1. 定義

線程終止狀態,運行完畢已經結束

2. 代碼及其效果圖

package demo_thread;/*** Created with IntelliJ IDEA.* Description:* User: 32309* Date: 2025-07-12* Time: 20:21*/
public class demo13_TERMINATED {public static void main(String[] args) throws InterruptedException {Thread thread = new Thread(() -> {for (int i = 0; i < 3; i++) {}});thread.start();while (true) {System.out.println(thread.getState());Thread.sleep(1000);}}
}

在這里插入圖片描述

(三)RUNNABLE

1. 定義

線程正在運行時狀態

2. 代碼及其效果圖

package demo_thread;/*** Created with IntelliJ IDEA.* Description:* User: 32309* Date: 2025-07-12* Time: 20:28*/
public class demo14_RUNNABLE {public static void main(String[] args) {Thread thread = new Thread(() -> {while (true) {}});thread.start();System.out.println(thread.getState());}
}

在這里插入圖片描述

(四)TIMED_WAITING

1. 定義

有時間限制的等待的線程狀態

2. 代碼及其效果圖

package demo_thread;/*** Created with IntelliJ IDEA.* Description:* User: 32309* Date: 2025-07-12* Time: 20:34*/
public class demo15_TINE_WAITING {public static void main(String[] args) throws InterruptedException {Thread thread = new Thread(() -> {while (true) {try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}});thread.start();thread.join(1000*10000);}
}

在這里插入圖片描述

(五)WAITING

1. 定義

沒有時間限制的等待的線程狀態

2. 代碼及其效果圖

package demo_thread;/*** Created with IntelliJ IDEA.* Description:* User: 32309* Date: 2025-07-12* Time: 20:39*/
public class demo16_WAITING {public static void main(String[] args) throws InterruptedException {Thread thread = new Thread(() -> {while (true) {}});thread.start();thread.join();}
}

在這里插入圖片描述

(六)BLOCKED&LOCK

阻塞,這里我們只討論的是加鎖后阻塞,提到鎖,不得不談到死鎖,有三種情況:
①:一個線程同時加鎖兩次
②:兩個線程兩把鎖,一個線程獲取到一把鎖之后,再嘗試獲取另一把鎖時,加鎖形成循環,那么就會形成死鎖!
③:N個線程M把鎖,每個線程運轉都需要用到兩把鎖的時候,就會形成循環,造成死鎖阻塞

(①)

觀察下方實例,我們可以發現,用 synchronized 的時候對一個線程多次加鎖,不會觸發阻塞,這說明 synchronized 是可重入鎖!

在這里插入圖片描述

package test;/*** Created with IntelliJ IDEA.* Description:* User: ran* Date: 2025-07-31* Time: 9:53* 一個線程多次加鎖*/
public class test1 {public static void main(String[] args) {Object lock = new Object();Thread thread1 = new Thread(() ->{synchronized (lock) {synchronized (lock) {System.out.println("多次加鎖!!!");}}   });thread1.start();}
}

(②)

觀察下面的實例可以看出,線程1lock1 加鎖后休眠1s, 再嘗試對第二個 lock2 加鎖時,會產生阻塞, 這是因為 線程2 已經對 lock2 加鎖成功, 又嘗試獲取 lock1 的時候產生了阻塞, 導致 lock2 沒有解鎖, 所以 線程1 嘗試獲取 lock2失敗, 產生阻塞, 相互循環, 形成死鎖
在這里插入圖片描述

package test;/*** Created with IntelliJ IDEA.* Description:* User: ran* Date: 2025-07-31* Time: 10:26*/
public class test2 {public static void main(String[] args) {Object lock1 = new Object();Object lock2 = new Object();Thread thread1 = new Thread(() -> {synchronized (lock1) {System.out.println("獲取第一把鎖: lock1");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}synchronized (lock2) {System.out.println("嘗試獲取第二把鎖: lock2");}}});Thread thread2 = new Thread(() -> {synchronized (lock2) {System.out.println("獲取第一把鎖: lock2");synchronized (lock1) {System.out.println("嘗試獲取第二把鎖: lock1");}}});thread1.start();thread2.start();}
}

(③)

通過下方實例,我們可以看出, N個對象M把鎖, 當每個人都要嵌套兩把鎖才能工作時,就會形成阻塞
在這里插入圖片描述

package test;/*** Created with IntelliJ IDEA.* Description:* User: ran* Date: 2025-07-31* Time: 10:54*/
public class test3 {public static void main(String[] args) {Object lock1 = new Object();Object lock2 = new Object();Object lock3 = new Object();Thread thread1 = new Thread(() -> {synchronized (lock1) {System.out.println("獲取第一把鎖: lock1");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}synchronized (lock2) {System.out.println("嘗試獲取第二把鎖: lock2");}}});Thread thread2 = new Thread(() -> {synchronized (lock2) {System.out.println("獲取第一把鎖: lock2");synchronized (lock3) {System.out.println("嘗試獲取第二把鎖: lock3");}}});Thread thread3 = new Thread(() -> {synchronized (lock3) {System.out.println("獲取第一把鎖: lock3");synchronized (lock1) {System.out.println("嘗試獲取第二把鎖: lock1");}}});thread1.start();thread2.start();thread3.start();}
}

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

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

相關文章

Linux---編輯器vim

一、vim的基本概念1.三種模式①命令模式控制屏幕光標的移動&#xff0c;字符、字或行的刪除&#xff0c;移動復制某區段及進入插入模式或者進去底行模式②插入模式可進行文本輸入&#xff0c;按Esc回到命令行模式③底行模式文件保存或退出&#xff0c;也可以進行文件替換&#…

如何在 Ubuntu 24.04 或 22.04 LTS Linux 上安裝 Guake 終端應用程序

通過本教程的簡單步驟,在 Ubuntu 24.04 或 22.04 LTS Jammy JellyFish 上安裝 Guake 終端以運行命令。 Guake(基于 Quake)是一個基于 Python 的終端模擬器。Guake 的行為類似于 Quake 中的終端:通過某個按鍵(熱鍵)按下時,窗口會從屏幕頂部滾下來,再次按下相同的按鍵時…

谷歌Gemini 2.5重磅應用:多模態研究助手Multi-Modal Researcher,實現全網自動研究與AI播客生成

在人工智能賦能科研與內容創作的浪潮中,谷歌基于其最新大模型 Gemini 2.5 推出了突破性工具 Multi-Modal Researcher。這一系統通過整合多模態數據(文本、視頻、實時網絡信息),實現了從自動研究到內容生成的全流程自動化。用戶只需輸入研究主題或YouTube視頻鏈接,系統即可…

防御綜合實驗

一、實驗拓補圖二、實驗需求及配置需求一設備接口VLAN接口類型SW2GE0/0/2VLAN 10AccessGE0/0/3VLAN 20AccessGE0/0/1VLAN List : 10 20Trunk[SW2]vlan 10 [SW2]vlan 20 [SW2]interface GigabitEthernet 0/0/2 [SW2-GigabitEthernet0/0/2]port link-type access [SW2-GigabitEt…

堆----2.前 K 個高頻元素

347. 前 K 個高頻元素 - 力扣&#xff08;LeetCode&#xff09; /** 桶排序: 首先遍歷數組,使用HashMap統計每個元素出現的次數 創建一個大小為length 1的List數組,下標代表元素出現次數,出現次數一致的元素放在同一個數組中 倒數遍歷List數組即可得得到前K個高頻元素 細節注…

如何分析Linux內存性能問題

一、Linux中的buffer與cache的區別 Linux的內存管理與監控_linux服務器虛假內存和真實內存怎么區分-CSDN博客文章瀏覽閱讀66次。本文主要是關于【Linux系統的物理內存與虛擬內存講解】【重點對虛擬內存的作用與用法進行了講解說明】【最后還對如何新增擴展、優化、刪除內存交換…

二次型 線性代數

知識結構總覽首先是我們的二次型的定義&#xff0c;就是說什么樣的才算是一個二次型。然后就是如何把二次型化為標準型&#xff0c;最后就是正定二次型的定義和判斷的一些條件。二次型的定義二次型其實是一種函數表達的方式&#xff0c;如上&#xff0c;含義其實就是每個項都是…

云原生三劍客:Kubernetes + Docker + Spring Cloud 實戰指南與深度整合

在當今微服務架構主導的時代&#xff0c;容器化、編排與服務治理已成為構建彈性、可擴展應用的核心支柱。本文將深入探討如何將 Docker&#xff08;容器化基石&#xff09;、Kubernetes&#xff08;編排引擎&#xff09;與 Spring Cloud&#xff08;微服務框架&#xff09; 無縫…

vue讓elementUI和elementPlus標簽內屬性支持rem單位

vue讓elementUI和elementPlus標簽內屬性支持rem單位 如 Element Plus 的 el-table 默認不直接支持使用 rem 作為列寬單位 解決方法: 將 rem 轉換為像素值&#xff08;基于根元素字體大小&#xff09; // 計算rem對應的像素值 const calcRem (remValue) > {// 獲取根元素(ht…

基于OAuth2與JWT的微服務API安全實戰經驗分享

引言 在微服務架構中&#xff0c;API 安全成為了保護服務免受未授權訪問和攻擊的關鍵要素。本文結合真實生產環境案例&#xff0c;以實戰經驗為出發點&#xff0c;分享基于 OAuth2 JWT 的微服務 API 安全方案&#xff0c;從業務場景、技術選型、實現細節、踩坑及解決方案&…

scrapy庫進階一

scrapy 庫復習 scrapy的概念&#xff1a;Scrapy是一個為了爬取網站數據&#xff0c;提取結構性數據而編寫的應用框架 scrapy框架的運行流程以及數據傳遞過程&#xff1a; 爬蟲中起始的url構造成request對象–>爬蟲中間件–>引擎–>調度器調度器把request–>引擎…

Objective-C實現iOS平臺微信步數修改指南

本文還有配套的精品資源&#xff0c;點擊獲取 簡介&#xff1a;本文介紹如何在iOS平臺上使用Objective-C語言&#xff0c;通過蘋果的HealthKit框架讀取和修改微信步數以及相關健康數據。首先介紹如何引入和使用HealthKit框架&#xff0c;包括請求權限、讀取步數數據、寫入步…

【ElementPlus】深入探索ElementPlus:前端界面的全能組件庫

&#x1f4da; 引言在現代 Web 開發中&#xff0c;創建既美觀又功能強大的用戶界面是一項挑戰。Element Plus&#xff0c;作為 Vue 3 生態中的明星 UI 組件庫&#xff0c;以其豐富的組件、優秀的性能和易用性贏得了廣大開發者的青睞。本文將全面覆蓋 Element Plus 的 常用核心組…

Json Jsoncpp

文章目錄Json 介紹Jsoncpp 介紹Json::Value序列化接口反序列化接口序列化操作反序列化操作Json 介紹 JSON&#xff08;JavaScript Object Notation&#xff0c;JavaScript 對象表示法&#xff09;是一種輕量級的數據交換格式&#xff0c;具有簡潔、易讀、跨平臺等特點&#xff…

openwrt下安裝istore(基于pve)

openwrt下安裝istore&#xff08;基于pve&#xff09;ssh連接到openwrt&#xff0c;用如下命令安裝istore&#xff1a;opkg update || exit 1cd /tmpwget https://github.com/linkease/openwrt-app-actions/raw/main/applications/luci-app-systools/root/usr/share/systools/i…

2025年Python Web框架之爭:Django、Flask還是FastAPI,誰將主宰未來?

文章概要 作為一名Python開發者&#xff0c;我經常被問到同一個問題&#xff1a;在2025年&#xff0c;Django、Flask和FastAPI哪個框架更值得使用&#xff1f;隨著技術的快速發展&#xff0c;這個問題的答案也在不斷變化。本文將全面比較這三個主流Python Web框架的特點、性能、…

高級11-Java日志管理:使用Log4j與SLF4J

在現代Java應用開發中&#xff0c;日志&#xff08;Logging&#xff09;是系統監控、調試、故障排查和性能分析的核心工具。一個高效、靈活、可配置的日志系統&#xff0c;不僅能幫助開發者快速定位問題&#xff0c;還能為運維團隊提供寶貴的運行時信息。在Java生態系統中&…

sc-atac的基礎知識(0)

sc-atac的基礎知識 **fragment**是ATAC-seq實驗中的一個重要概念&#xff0c;它指的是通過Tn5轉座酶對DNA分子進行酶切&#xff0c;然后經由雙端測序得到的序列。根據Tn5插入導致的偏移從read比對得到的位置推斷出fragment的起始和結束位置。根據之前的報道&#xff0c;Tn5轉座…

Python從入門到精通計劃Day01: Python開發環境搭建指南:從零開始打造你的“數字廚房“

目錄一、配置你的「魔杖」&#xff1a;Python 3.x安裝1.1 跨平臺安裝指南1.2 驗證你的「法力值」二、選擇你的「魔法工坊」&#xff1a;IDE配置2.1 VS Code&#xff1a;輕量級實驗室2.2 PyCharm&#xff1a;專業級法師塔三、施展第一個「魔咒」&#xff1a;Hello World3.1 基礎…

MCP Agent 工程框架Dify初探

目錄引言一、Dify是什么二、為什么使用Dify三、使用Dify要怎么做1、聊天助手2、Agent2.1 Function calling&#xff08;函數調用&#xff09;和 ReAct 兩種推理模式的區別2.1.1 技術本質與工作流程對比2.1.2 優缺點對比2.1.3 適用場景與選擇依據2.2 LangChain 的 Agent 實現原理…