Thread類的基本用法及Java線程的幾種狀態(tài)示例詳解
在Java中,Thread類是多線程編程的核心。
線程創(chuàng)建 (Thread Creation)
- 創(chuàng)建線程主要有兩種邏輯:繼承Thread類或?qū)崿F(xiàn)Runnable接口。
- 方式1:繼承 Thread 類,重寫run()
// 自定義線程類繼承Thread
class MyThread extends Thread {
// 重寫run(),定義線程執(zhí)行邏輯
@Override
public void run() {
System.out.println("子線程執(zhí)行:" + Thread.currentThread().getName());
}
}
// 使用
public class Demo {
public static void main(String[] args) {
MyThread t = new MyThread();
t.start(); // 3. 調(diào)用start()啟動線程(不能直接調(diào)用run())
}
}
- 方式2:實(shí)現(xiàn)Runnable接口,傳給Thread
// 實(shí)現(xiàn)Runnable接口
class MyRunnable implements Runnable {
@Override
public void run() {
System.out.println("子線程執(zhí)行:" + Thread.currentThread().getName());
}
}
// 使用
public class Demo {
public static void main(String[] args) {
// 把Runnable實(shí)例傳給Thread
Thread t = new Thread(new MyRunnable());
t.start(); // 啟動線程
}
}
線程中斷 (Thread Interruption)
- 線程中斷不是強(qiáng)制停止線程,而是一種協(xié)作機(jī)制,即給線程發(fā)一個(gè)“請停止”的信號。
- void interrupt():標(biāo)記線程為 “中斷狀態(tài)”
- boolean isInterrupted():判斷線程是否處于中斷狀態(tài)
- 若線程在sleep/wait/join時(shí)被中斷,會拋出InterruptedException,且中斷狀態(tài)會被清除
Thread t = new Thread(() -> {
while (!Thread.currentThread().isInterrupted()) { // 檢測中斷狀態(tài)
System.out.println("線程運(yùn)行中...");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// 捕獲中斷異常后,中斷狀態(tài)會被清除,需手動終止循環(huán)
System.out.println("線程被中斷");
Thread.currentThread().interrupt(); // 重新標(biāo)記中斷(可選)
break;
}
}
});
t.start();
// 主線程1秒后中斷子線程
Thread.sleep(1000);
t.interrupt();
線程等待 (Thread Join)
- 有時(shí)主線程需要等待子線程執(zhí)行完畢后再繼續(xù)執(zhí)行,這時(shí)可以使用join()。
- t.join():當(dāng)前線程會進(jìn)入阻塞狀態(tài),直到線程t執(zhí)行結(jié)束。
- 帶參數(shù)的 join(long millis):設(shè)置最大等待時(shí)間,如果超時(shí)線程還沒結(jié)束,當(dāng)前線程就不再等待。
Thread t = new Thread(() -> {
System.out.println("子線程開始執(zhí)行");
try { Thread.sleep(2000); } catch (InterruptedException e) {}
System.out.println("子線程執(zhí)行完畢");
});
t.start();
// 主線程等待t執(zhí)行完(最多等3秒)
t.join(3000);
System.out.println("主線程繼續(xù)執(zhí)行");
線程休眠 (Thread Sleep)
- static void sleep(long millis):讓當(dāng)前線程暫停指定時(shí)間(不會釋放鎖),拋出InterruptedException
System.out.println("開始休眠");
try {
Thread.sleep(2000); // 當(dāng)前線程休眠2秒
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("休眠結(jié)束");
獲取線程實(shí)例 (Get Current Instance)
- 在編寫通用代碼(尤其是 Runnable 中)時(shí),常需要知道是誰在運(yùn)行。
- Thread.currentThread():返回代碼當(dāng)前正在執(zhí)行的那個(gè)線程對象的引用。
- 常用操作:獲取線程 ID (getId())、獲取線程名稱 (getName()) 等。
// 獲取當(dāng)前線程(這里是main線程)
Thread mainThread = Thread.currentThread();
System.out.println("當(dāng)前線程名:" + mainThread.getName()); // 輸出"main"
// 子線程實(shí)例
Thread t = new Thread(() -> {
Thread current = Thread.currentThread();
System.out.println("子線程名:" + current.getName()); // 輸出"Thread-0"
});
t.start();
Java線程的幾種狀態(tài)
線程狀態(tài)一共有幾種?
- Java線程共有6種狀態(tài):
- NEW (新建)
- RUNNABLE (可運(yùn)行)
- BLOCKED (阻塞)
- WAITING (等待)
- TIMED_WAITING (超時(shí)等待)
- TERMINATED (終止)
每種狀態(tài)的含義與切換條件
- NEW (新建)
- 含義:創(chuàng)建了線程對象(new Thread()),但尚未調(diào)用 start() 方法。
- 切換:調(diào)用 start() 方法后,進(jìn)入 RUNNABLE 狀態(tài)。
- RUNNABLE (可運(yùn)行)
- 含義:Java 將操作系統(tǒng)中的“就緒(Ready)”和“運(yùn)行中(Running)”兩種狀態(tài)統(tǒng)稱為 RUNNABLE。處于該狀態(tài)的線程可能正在 CPU 上執(zhí)行,也可能正在等待操作系統(tǒng)分配時(shí)間片。
- 切換:
- 就緒 -> 運(yùn)行:獲得 CPU 時(shí)間片。
- 運(yùn)行 -> 就緒:CPU 時(shí)間片用完,或主動調(diào)用 Thread.yield()。
- BLOCKED (阻塞)
- 含義:線程正在等待獲取一個(gè)排他鎖(如進(jìn)入synchronized 代碼塊/方法),但該鎖目前被其他線程持有。
- 切換:
- RUNNABLE -> BLOCKED:嘗試進(jìn)入 synchronized 區(qū)域失敗。
- BLOCKED -> RUNNABLE:其他線程釋放鎖,當(dāng)前線程成功競爭到鎖。
- WAITING (等待)
- 含義:線程處于無限期的等待狀態(tài),不會被分配 CPU 時(shí)間,必須等待其他線程顯式地喚醒。
- 切換:
- RUNNABLE -> WAITING:調(diào)用 Object.wait()(不帶參數(shù))、Thread.join()(不帶參數(shù))或 LockSupport.park()。
- WAITING -> RUNNABLE:其他線程調(diào)用 Object.notify()、notifyAll() 或 LockSupport.unpark()。
- TIMED_WAITING (超時(shí)等待)
- 含義:與 WAITING 類似,但在指定的時(shí)間后會自動喚醒,不需要其他線程顯式喚醒。
- 切換:
- RUNNABLE -> TIMED_WAITING:調(diào)用 Thread.sleep(ms)、Object.wait(ms)、Thread.join(ms) 等帶時(shí)間參數(shù)的方法。
- TIMED_WAITING -> RUNNABLE:時(shí)間結(jié)束,或被提前喚醒(如 notify())。
- TERMINATED (終止)
- 含義:線程已經(jīng)執(zhí)行完畢(run() 方法正常結(jié)束)或因異常退出了執(zhí)行。
- 切換:線程一旦進(jìn)入此狀態(tài),生命周期結(jié)束,不可再次啟動(再次調(diào)用 start() 會拋出異常)。
總結(jié)
到此這篇關(guān)于Thread類基本用法及Java線程幾種狀態(tài)的文章就介紹到這了,更多相關(guān)Thread類用法及Java線程狀態(tài)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot配置ShedLock分布式定時(shí)任務(wù)
ShedLock是一個(gè)在分布式環(huán)境中使用的定時(shí)任務(wù)框架,這篇文章主要介紹了SpringBoot配置ShedLock分布式定時(shí)任務(wù),需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-05-05
基于java下載中g(shù)etContentLength()一直為-1的一些思路
下面小編就為大家?guī)硪黄趈ava下載中g(shù)etContentLength()一直為-1的一些思路。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-06-06
Java線程休眠_(dá)動力節(jié)點(diǎn)Java學(xué)院整理
sleep() 的作用是讓當(dāng)前線程休眠,即當(dāng)前線程會從“運(yùn)行狀態(tài)”進(jìn)入到“休眠(阻塞)狀態(tài)”。下面通過實(shí)例代碼給大家介紹Java線程休眠的知識,需要的朋友參考下吧2017-05-05
使用EasyExcel實(shí)現(xiàn)簡單的Excel表格解析操作
這篇文章主要介紹了如何使用EasyExcel完成簡單的表格解析操作,同時(shí)實(shí)現(xiàn)了大量數(shù)據(jù)情況下數(shù)據(jù)的分次批量入庫,并記錄每條數(shù)據(jù)入庫的狀態(tài),感興趣的可以了解下2025-03-03
spring cloud alibaba Nacos 注冊中心搭建過程詳解
這篇文章主要介紹了spring cloud alibaba Nacos 注冊中心搭建過程詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-10-10
Spring?Boot項(xiàng)目使用WebClient調(diào)用第三方接口的詳細(xì)教程(附實(shí)例代碼)
WebClient是Spring WebFlux模塊提供的一個(gè)非阻塞的基于響應(yīng)式編程的進(jìn)行Http請求的客戶端工具,從Spring5.0開始提供,這篇文章主要介紹了Spring?Boot項(xiàng)目使用WebClient調(diào)用第三方接口的相關(guān)資料,需要的朋友可以參考下2025-09-09

