Java標(biāo)準(zhǔn)庫(kù)中Thread類的基本用法總結(jié)大全
前言
線程是操作系統(tǒng)中的概念,操作系統(tǒng)內(nèi)核實(shí)現(xiàn)了線程這樣的概念,并且對(duì)用戶層提供了一些api,供用戶使用。在Java標(biāo)準(zhǔn)庫(kù)中,Thread
類可以視為是對(duì)操作系統(tǒng)提供的api進(jìn)一步的抽象和封裝。
Thread 類的基本用法有:
一、線程創(chuàng)建
想要實(shí)現(xiàn)多線程編程,第一步就是需要?jiǎng)?chuàng)建一個(gè)線程。在Java中創(chuàng)建線程的方式有多種方式,下面介紹五種常見(jiàn)的創(chuàng)建方式:
方式1:繼承Thread類,重寫run方法!
- 創(chuàng)建一個(gè)繼承Thread類的子類
- 重寫run()方法,編寫線程執(zhí)行的代碼
- 創(chuàng)建子類實(shí)例并調(diào)用start()方法啟動(dòng)線程
優(yōu)點(diǎn):編碼簡(jiǎn)單
缺點(diǎn):Java是單繼承,繼承Thread后無(wú)法繼承其他類
class MyThread extends Thread{
@Override
public void run() {
System.out.println("方式1:繼承Thread類,重寫run方法!");
}
}
//創(chuàng)建對(duì)象,并調(diào)用start()方法啟動(dòng)線程
Thread t = new MyThread();
t.start();
方式2:實(shí)現(xiàn) Runnable, 重寫 run方法
- 創(chuàng)建一個(gè)實(shí)現(xiàn)Runnable接口的類
- 實(shí)現(xiàn)run()方法,編寫線程執(zhí)行的代碼
- 創(chuàng)建Thread實(shí)例,傳入Runnable實(shí)現(xiàn)類對(duì)象
優(yōu)點(diǎn):可以繼承其他類,實(shí)現(xiàn)多個(gè)接口,更靈活
class MyRunnable implements Runnable{
@Override
public void run() {
System.out.println("方式2:實(shí)現(xiàn) Runnable, 重寫 run");
}
}
//創(chuàng)建對(duì)象,并調(diào)用start()方法啟動(dòng)線程
Thread t = new Thread(new MyRunnable());
t.start();
方式3: 繼承Thread, 重寫run, 使用匿名內(nèi)部類
- 直接創(chuàng)建Thread的匿名子類
- 在匿名內(nèi)部類中重寫run()方法
- 適用于簡(jiǎn)單、一次性使用的線程
Thread t = new Thread(){
@Override
public void run() {
System.out.println("方式3:繼承Thread, 重寫run, 使用匿名內(nèi)部類");
}
};
方式4: 實(shí)現(xiàn)Runnable, 重寫run, 使用匿名內(nèi)部類
- 創(chuàng)建Runnable接口的匿名實(shí)現(xiàn)類
- 在匿名內(nèi)部類中實(shí)現(xiàn)run()方法
- 將匿名Runnable對(duì)象傳遞給Thread構(gòu)造函數(shù)
- 比繼承Thread的匿名內(nèi)部類更靈活
Thread t = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("方式4: 實(shí)現(xiàn)Runnable, 重寫run, 使用匿名內(nèi)部類");
}
});
方式5: 使用lambda表達(dá)式
- Runnable是函數(shù)式接口,可以使用lambda表達(dá)式
- 語(yǔ)法簡(jiǎn)潔,適合簡(jiǎn)單的線程任務(wù)
- 代碼更簡(jiǎn)潔
Thread t = new Thread(()->{
System.out.println("方式5: 使用lambda表達(dá)式");
});
二、線程中斷 - interrupt()
線程一旦啟動(dòng)進(jìn)入工作狀態(tài),它就會(huì)根據(jù)代碼編寫的步驟去執(zhí)行,一直到完成為止才結(jié)束。但是有時(shí)需臨時(shí)打斷它的執(zhí)行,Thread類中提供了interrupt方法去實(shí)現(xiàn)這一功能。
interrupt() 是 Thread類的一個(gè)實(shí)例方法,用于中斷線程。它設(shè)置線程的中斷狀態(tài)標(biāo)志,但不會(huì)強(qiáng)制停止線程的執(zhí)行。線程自身需要檢查中斷狀態(tài)并決定如何響應(yīng)。
thread.interrupt(); // 設(shè)置線程的中斷標(biāo)志位為 true Thread.interrupted(); // 檢查當(dāng)前線程是否被中斷(會(huì)清除中斷狀態(tài)) thread.isInterrupted(); // 檢查對(duì)象關(guān)聯(lián)的線程是否被中斷(不會(huì)清除中斷狀態(tài))
例如下面代碼實(shí)現(xiàn)中斷:
public class Demo3 {
public static void main(String[] args) throws InterruptedException {
Thread worker = new Thread(() -> {
while(!Thread.interrupted()){
System.out.println("工作中...");
}
System.out.println("線程正常結(jié)束");
});
worker.start();//啟動(dòng)線程
Thread.sleep(3000);//讓線程工作三秒
worker.interrupt(); //中斷線程
}
}
結(jié)果:

我們讓線程工作三秒鐘,此時(shí)while循環(huán)每次循環(huán)開(kāi)始前檢查中斷狀態(tài),當(dāng)執(zhí)行執(zhí)行中斷指令后,線程結(jié)束循環(huán),但線程不會(huì)強(qiáng)制停止線程的執(zhí)行,繼續(xù)把線程正常結(jié)束語(yǔ)句繼續(xù)打印完后再結(jié)束。
另外,如果線程因?yàn)檎{(diào)用wait/join/sleep等方法而阻塞掛起,則以InterruptionException異常的形式拋出,中斷狀態(tài)會(huì)被清除(變?yōu)?false),如果不重新設(shè)置中斷狀態(tài),while 循環(huán)會(huì)繼續(xù)執(zhí)行!
所以要在catch后恢復(fù)中斷狀態(tài),確保了中斷信號(hào)不會(huì)丟失,從而讓while 循環(huán)的條件檢查能檢測(cè)到中斷,線程就能正常退出。
public class Demo3 {
public static void main(String[] args) throws InterruptedException {
Thread worker = new Thread(() -> {
while(!Thread.currentThread().isInterrupted()){
System.out.println("工作中...");
try {
Thread.sleep(1000);//sleep() 被中斷時(shí):會(huì)拋出 InterruptedException 并清除中斷狀態(tài)(false)
} catch (InterruptedException e) {
System.out.println("線程在sleep時(shí)被中斷");
Thread.currentThread().interrupt(); //中斷狀態(tài)恢復(fù)為true
//確保了中斷信號(hào)不會(huì)丟失,
//確保了while 循環(huán)的條件檢查能檢測(cè)到中斷
//確保了線程能正常退出
}
}
System.out.println("線程正常結(jié)束");
});
worker.start();//啟動(dòng)線程
Thread.sleep(1000);//讓線程工作三秒
worker.interrupt(); //中斷線程
}
}
三、線程等待 - join()
有時(shí)候,當(dāng)有多個(gè)線程并發(fā)工作時(shí),可能需要某個(gè)線程先執(zhí)行完任務(wù)后,后一個(gè)線程再根據(jù)前一個(gè)線程執(zhí)行結(jié)束的結(jié)果去進(jìn)行自己的下一步工作時(shí),就需要有一個(gè)先后執(zhí)行順序,此時(shí)可以使用join方法去實(shí)現(xiàn)。
栗如:
public class Demo {
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(new Runnable() {
@Override
public void run() {
System.out.print("1");
}
});
t.start();
t.join();
System.out.print("2");
}
}
當(dāng)主線程創(chuàng)建一個(gè)新線程 t 后,我們調(diào)用start方法啟動(dòng)線程,再調(diào)用join方法讓main主線程等待,等打印完 “1” 后,主線程再執(zhí)行打印 “2” 操作,因此最終結(jié)果為 “12”。
如果不使用join方法,會(huì)出現(xiàn)兩種結(jié)果,分別是“12” 或者是“21”。因此t線程和main線程是并發(fā)執(zhí)行的,他們的執(zhí)行順序都是操作系統(tǒng)隨機(jī)調(diào)度的,為了保證結(jié)果為 “12”,就得保證t線程優(yōu)先執(zhí)行,此時(shí)就可以調(diào)用join方法,使main線程等待。
四、線程休眠 - sleep()
調(diào)用sleep方法可以使線程暫時(shí)進(jìn)入休眠狀態(tài),單位為毫秒,比如sleep(3000)就是休眠三秒鐘。
五、獲取線程實(shí)例 - currentThread()
返回當(dāng)前線程對(duì)象的引用
例如:

小結(jié)
以上就是Java標(biāo)準(zhǔn)庫(kù)中Thread類的一些基本用法,由于個(gè)人水平有限,如有不足之處,歡迎一起交流學(xué)習(xí)共同進(jìn)步!
到此這篇關(guān)于Java標(biāo)準(zhǔn)庫(kù)中Thread類的基本用法總結(jié)大全的文章就介紹到這了,更多相關(guān)Java標(biāo)準(zhǔn)庫(kù)Thread類用法內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
idea環(huán)境下Maven無(wú)法正常下載pom中配置的包問(wèn)題
這篇文章主要介紹了idea環(huán)境下Maven無(wú)法正常下載pom中配置的包的問(wèn)題,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-06-06
java基于RMI遠(yuǎn)程過(guò)程調(diào)用詳解
這篇文章主要為大家詳細(xì)介紹了java基于RMI遠(yuǎn)程過(guò)程調(diào)用,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-08-08
Java擴(kuò)展庫(kù)RxJava的基本結(jié)構(gòu)與適用場(chǎng)景小結(jié)
RxJava(GitHub: https://github.com/ReactiveX/RxJava)能夠幫助Java進(jìn)行異步與事務(wù)驅(qū)動(dòng)的程序編寫,這里我們來(lái)作一個(gè)Java擴(kuò)展庫(kù)RxJava的基本結(jié)構(gòu)與適用場(chǎng)景小結(jié),剛接觸RxJava的同學(xué)不妨看一下^^2016-06-06
Java集合之Set接口及其實(shí)現(xiàn)類精解
set接口是繼承自Collection的子接口,特點(diǎn)是元素不重復(fù),存儲(chǔ)無(wú)序。在set接口的實(shí)現(xiàn)類中添加重復(fù)元素是不會(huì)成功的,判斷兩個(gè)元素是否重復(fù)根據(jù)元素類重寫的2021-09-09
SpringBoot事件機(jī)制相關(guān)知識(shí)點(diǎn)匯總
這篇文章主要介紹了SpringBoot事件機(jī)制相關(guān)知識(shí)點(diǎn)匯總,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-09-09
netflix.discovery.shared.transport.TransportException:Cannot
這篇文章主要介紹了netflix.discovery.shared.transport.TransportException:Cannot execute request on any known server報(bào)錯(cuò)問(wèn)題及解決方法,感興趣的朋友一起看看吧2023-09-09
SpringBoot項(xiàng)目部署到服務(wù)器上的方法(Jar包)
這篇文章主要介紹了SpringBoot項(xiàng)目部署到服務(wù)器上的方法(Jar包),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-01-01
MyBatis插件實(shí)現(xiàn)SQL執(zhí)行耗時(shí)監(jiān)控
MyBatis插件(Plugin)是其框架擴(kuò)展性的核心,本文深入剖析插件實(shí)現(xiàn)原理,手把手教你開(kāi)發(fā)企業(yè)級(jí)SQL監(jiān)控插件,有需要的小伙伴可以了解下2025-12-12

