Java線程詳解

線程創(chuàng)建的幾種方式

通過Callable,需要實(shí)現(xiàn)call方法

通過FutureTask創(chuàng)建

FutureTask是Future接口的實(shí)現(xiàn),它實(shí)現(xiàn)了一個(gè)可以提交給Executor執(zhí)行的任務(wù),并且可以用來檢查任務(wù)的執(zhí)行狀態(tài)和獲取任務(wù)的執(zhí)行結(jié)果。

通過線程池(ExecutorService)

Java線程狀態(tài)

New(新建狀態(tài)):當(dāng)線程對象被創(chuàng)建但尚未調(diào)用 `start()` 方法時(shí),線程處于新建狀態(tài)。

Runnable(可運(yùn)行狀態(tài)):一旦線程調(diào)用了 `start()` 方法,它就進(jìn)入了可運(yùn)行狀態(tài)。在可運(yùn)行狀態(tài)下,線程可能正在執(zhí)行,也可能正在等待系統(tǒng)資源(如處理器時(shí)間片)。

READY(就緒):線程對象創(chuàng)建后,調(diào)用了該對象的`start()`方法。該狀態(tài)的線程位于可運(yùn)行線程池中,等待被線程調(diào)度選中并分配cpu使用權(quán)。2. ?Running(運(yùn)行狀態(tài)):在可運(yùn)行狀態(tài)下,線程可能被線程調(diào)度器選擇執(zhí)行,并開始執(zhí)行線程的 `run()` 方法。線程進(jìn)入運(yùn)行狀態(tài)后,會(huì)根據(jù)系統(tǒng)的調(diào)度算法分配到處理器上執(zhí)行。

Blocked(阻塞狀態(tài)):在某些情況下,線程可能會(huì)被阻塞,暫停執(zhí)行。當(dāng)線程等待某個(gè)條件的發(fā)生時(shí),它進(jìn)入了阻塞狀態(tài)。例如,線程可能因?yàn)榈却i、等待輸入/輸出或等待其他線程的通知而進(jìn)入阻塞狀態(tài)。

Waiting(等待狀態(tài)):線程在等待某個(gè)特定條件的發(fā)生時(shí),會(huì)進(jìn)入等待狀態(tài)。線程可以通過調(diào)用 `wait()` 方法、`join()` 方法或者 `LockSupport.park()` 方法來進(jìn)入等待狀態(tài)。

Timed Waiting(計(jì)時(shí)等待狀態(tài)):類似于等待狀態(tài),線程可以通過調(diào)用帶有超時(shí)參數(shù)的 `Thread.sleep()` 方法、`Object.wait()` 方法或者 `Thread.join()`方法來進(jìn)入計(jì)時(shí)等待狀態(tài)。

Terminated(終止?fàn)顟B(tài)):當(dāng)線程的 `run()` 方法執(zhí)行完畢或者出現(xiàn)未捕獲的異常時(shí),線程將進(jìn)入終止?fàn)顟B(tài)。終止?fàn)顟B(tài)表示線程已經(jīng)完成了它的生命周期,并且不再執(zhí)行。

狀態(tài)流轉(zhuǎn)如下圖所示:

sleep與wait區(qū)別

方法調(diào)用位置和鎖的釋放:

sleep()是Thread類的靜態(tài)方法,可以在任何地方使用。它使當(dāng)前線程休眠指定的時(shí)間,不會(huì)釋放對象鎖。

wait()是Object類的方法,只能在同步塊或同步方法中使用。它會(huì)使當(dāng)前線程釋放對象的鎖,并進(jìn)入等待狀態(tài),直到其他線程調(diào)用相同對象上的notify()或notifyAll()方法來喚醒等待的線程。

使用場景:

sleep()通常用于模擬線程執(zhí)行過程中的暫停,定時(shí)任務(wù)等。它不依賴于對象的鎖,因此可以在任何時(shí)候使用。

wait()通常用于線程間的協(xié)調(diào)和通信。它必須在同步塊或同步方法中使用,以便在等待時(shí)釋放對象鎖,讓其他線程能夠進(jìn)入同步塊或同步方法進(jìn)行操作。

異常處理:

sleep()在休眠期間不會(huì)被中斷,但會(huì)拋出InterruptedException異常,可以通過捕獲該異常進(jìn)行處理。

wait()在等待期間可以被其他線程調(diào)用interrupt()方法中斷,會(huì)拋出InterruptedException異常。此外,還可以使用wait()方法的重載版本來設(shè)置等待超時(shí)時(shí)間。

    調(diào)用方式:

    sleep()方法直接通過Thread類調(diào)用,例如:Thread.sleep(1000);。

    wait()方法必須通過持有對象的鎖調(diào)用,例如:synchronized (obj) { obj.wait(); }。sleep()主要用于控制線程的休眠時(shí)間,不釋放鎖,而wait()主要用于線程間的協(xié)調(diào)與通信,釋放對象的鎖。

    object.wait()與Objetc.wait(long)區(qū)別

    Object.wait()和Object.wait(long millis)是Object類中的方法,用于使當(dāng)前線程進(jìn)入等待狀態(tài),直到其他線程通過調(diào)用相同對象的notify()或notifyAll()方法來喚醒等待的線程。它們之間的區(qū)別在于等待的方式和超時(shí)設(shè)置。

    Object.wait()

    wait()方法讓當(dāng)前線程進(jìn)入無限期等待狀態(tài),直到其他線程調(diào)用相同對象的notify()或notifyAll()方法來喚醒等待的線程。

    調(diào)用wait()方法后,當(dāng)前線程會(huì)釋放對象的鎖,并進(jìn)入等待隊(duì)列中,直到被其他線程喚醒。

    Object.wait(long millis)

    wait(long millis)方法讓當(dāng)前線程進(jìn)入等待狀態(tài),最多等待指定的毫秒數(shù),超過指定時(shí)間后線程會(huì)自動(dòng)喚醒。

    調(diào)用wait(long millis)方法后,當(dāng)前線程會(huì)釋放對象的鎖,并進(jìn)入等待隊(duì)列中,直到被其他線程喚醒或超時(shí)時(shí)間到達(dá)。

    Thread.sleep()與Thread.sleep(long)區(qū)別

    在調(diào)用Thread.sleep()方法時(shí),有參數(shù)和無參數(shù)的版本會(huì)導(dǎo)致線程的狀態(tài)稍有不同。

    無參數(shù)的Thread.sleep()

    無參數(shù)版本的Thread.sleep()實(shí)際上是調(diào)用了帶有一個(gè)參數(shù)的Thread.sleep(longmillis)方法,并將參數(shù)值設(shè)為0,表示休眠0毫秒。

    當(dāng)線程調(diào)用無參數(shù)的Thread.sleep()時(shí),它會(huì)暫停執(zhí)行一段時(shí)間,時(shí)間長度由操作系統(tǒng)調(diào)度決定。在這種情況下,線程的狀態(tài)仍然保持為`RUNNABLE`,表示線程可執(zhí)行但未必正在執(zhí)行,只是暫時(shí)停止了執(zhí)行。

    有參數(shù)的Thread.sleep(long millis)

    當(dāng)線程調(diào)用有參數(shù)的Thread.sleep(long millis)時(shí),它會(huì)暫停執(zhí)行指定的時(shí)間,時(shí)間長度由傳入的參數(shù)決定。

    在這種情況下,線程的狀態(tài)也是TIMED_WAITING(定時(shí)等待),表示線程正在等待指定的時(shí)間,暫時(shí)停止了執(zhí)行。

    ?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
    【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
    平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

    相關(guān)閱讀更多精彩內(nèi)容

    • 什么是線程: 當(dāng)操作系統(tǒng)運(yùn)行一個(gè)程序時(shí)會(huì)為其創(chuàng)建一個(gè)進(jìn)程,一個(gè)進(jìn)程里可以創(chuàng)建多個(gè)線程,這些線程都擁有各自的程序計(jì)數(shù)...
      藍(lán)色空間號閱讀 432評論 0 0
    • 線程是程序執(zhí)行的最小單元,多線程是指程序同一時(shí)間可以有多個(gè)執(zhí)行單元運(yùn)行(這個(gè)與你的CPU核心有關(guān))。 在java中...
      程序員技術(shù)圈閱讀 1,068評論 2 17
    • 線程對象是可以產(chǎn)生線程的對象。比如在 Java 平臺(tái)中 Thread 對象 、Runnable 對象。線程,是指正...
      Alei_Android閱讀 492評論 0 0
    • 基本概念 多線程: 指的是這個(gè)程序(一個(gè)進(jìn)程)運(yùn)行時(shí)產(chǎn)生了不止一個(gè)線程 并行: 多個(gè)cpu實(shí)例或者多臺(tái)機(jī)器同時(shí)執(zhí)行...
      孤獨(dú)的根號十二閱讀 4,408評論 1 11
    • 一、前提 最近有點(diǎn)懶散,沒什么比較有深度的產(chǎn)出。剛好想重新研讀一下JUC線程池的源碼實(shí)現(xiàn),在此之前先深入了解一下J...
      Java_蘇先生閱讀 1,538評論 1 10

    友情鏈接更多精彩內(nèi)容