Java多線程編程

為了滿足業(yè)務(wù)需求,無(wú)論P(yáng)C(個(gè)人計(jì)算機(jī))還是智能手機(jī)(Smart Phone)現(xiàn)在都支持多任務(wù),都能夠編寫(xiě)并發(fā)訪問(wèn)程序。多線程編程可以編寫(xiě)并發(fā)訪問(wèn)程序。

在多線程O(píng)S(操作系統(tǒng))中,通常是在一個(gè)進(jìn)程中包括多個(gè)線程,每個(gè)線程都是作為利用CPU的基本單位,是花費(fèi)最小開(kāi)銷(xiāo)的實(shí)體。一般可以在同一時(shí)間內(nèi)執(zhí)行多個(gè)程序的操作系統(tǒng)都有進(jìn)程的概念。

打開(kāi)Windows當(dāng)前運(yùn)行的進(jìn)程,如圖所示:

進(jìn)程

一個(gè)進(jìn)程就是一個(gè)執(zhí)行中的程序,而每一個(gè)進(jìn)程都有自己獨(dú)立的一塊內(nèi)存空間、一組系統(tǒng)資源。在進(jìn)程的概念中,每一個(gè)進(jìn)程的內(nèi)部數(shù)據(jù)和狀態(tài)都是完全獨(dú)立的。

在Windows操作系統(tǒng)中一個(gè)進(jìn)程就是一個(gè)exe或者dll程序,它們相互獨(dú)立,互相也可以通信,在智能手機(jī)操作系統(tǒng)中進(jìn)程間的通信應(yīng)用也是很多的。

線程

線程與進(jìn)程相似,是一段完成某個(gè)特定功能的代碼,是程序中單個(gè)順序控制的流程,但與進(jìn)程不同的是,同類的多個(gè)線程是共享一塊內(nèi)存空間和一組系統(tǒng)資源。所以系統(tǒng)在各個(gè)線程之間切換時(shí),開(kāi)銷(xiāo)要比進(jìn)程小的多,正因如此,線程被稱為輕量級(jí)進(jìn)程。一個(gè)進(jìn)程中可以包含多個(gè)線程。

主線程

Java程序至少會(huì)有一個(gè)線程,這就是主線程,程序啟動(dòng)后是由JVM(Java虛擬機(jī))創(chuàng)建主線程,程序結(jié)束時(shí)由JVM停止主線程。主線程和子線程的關(guān)系是主線程它負(fù)責(zé)管理子線程,即子線程的啟動(dòng)、掛起、停止等等操作。

進(jìn)程、主線程和子線程關(guān)系如圖所示:

獲取主線程示例代碼如下:

publicclass MyThread{

? ? publicstatic void main(String[] args) {

? ? ? //獲取主線程

? ? ? Thread thread= Thread.currentThread();

? ? ? System.out.println("主線程名:" + thread.getName());

? ? }

}

線程的狀態(tài)

在線程的生命周期中,線程會(huì)有幾種狀態(tài),如圖所示,線程有5種狀態(tài)。下面分別介紹:


1. 新建狀態(tài)

? ? ? ? 新建狀態(tài)(New)是通過(guò)new等方式創(chuàng)建線程對(duì)象,它僅僅是一個(gè)空的線程對(duì)象。

2. 就緒狀態(tài)

? ? ? 當(dāng)主線程調(diào)用新建線程的start()方法后,它就進(jìn)入就緒狀態(tài)(Runnable),此時(shí)的線程尚未真正? ? ? ? 開(kāi)? ? 始執(zhí)行run()方法,它必須等待CPU的調(diào)度。

3. 運(yùn)行狀態(tài)

? ? ? CPU的調(diào)度就緒狀態(tài)的線程,線程進(jìn)入運(yùn)行狀態(tài)(Running),處于運(yùn)行狀態(tài)的線程獨(dú)占CPU,? ? ? ? 執(zhí)行run()方法。

4. 阻塞狀態(tài)

? ? ? 因?yàn)槟撤N原因運(yùn)行狀態(tài)的線程會(huì)進(jìn)入不可運(yùn)行狀態(tài),即阻塞狀(Blocked),處于阻塞狀態(tài)的線? ? ? 程JVM系統(tǒng)不能執(zhí)行該線程,即使CPU空閑。如下幾個(gè)原因會(huì)導(dǎo)致線程進(jìn)入阻塞狀態(tài):

? ? ? ? 1)當(dāng)前線程調(diào)用sleep()方法,進(jìn)入休眠狀態(tài)。

? ? ? ? 2)被其他線程調(diào)用了join()方法,等待其他線程結(jié)束。

? ? ? ? 3)發(fā)出I/O請(qǐng)求,等待I/O操作完成期間。

? ? ? ? 4)當(dāng)前線程調(diào)用wait()方法。

5. 死亡狀態(tài)

線程退出run()方法后,就會(huì)進(jìn)入死亡狀態(tài)(Dead),線程進(jìn)入死亡狀態(tài)有可以是正常實(shí)現(xiàn)完成? ? ? run()方法進(jìn)入,也可能是由于發(fā)生異常而進(jìn)入的。

線程間通信

如果兩個(gè)線程之間有依賴關(guān)系,線程之間必須進(jìn)行通信,互相協(xié)調(diào)才能完成(任務(wù))工作。

例如,一個(gè)線程生成了一些數(shù)據(jù),將數(shù)據(jù)壓棧;另一個(gè)線程需要這些數(shù)據(jù),將數(shù)據(jù)出棧。這兩個(gè)線程互相依賴,當(dāng)堆棧為空時(shí),消費(fèi)線程無(wú)法取出數(shù)據(jù)時(shí),應(yīng)該通知生成線程添加數(shù)據(jù);當(dāng)堆棧已滿時(shí),生產(chǎn)線程無(wú)法添加數(shù)據(jù)時(shí),應(yīng)該通知消費(fèi)線程取出數(shù)據(jù)。

完成線程間的通信,在Java中有幾個(gè)方法:

? ? (1)void wait():使當(dāng)前線程釋放對(duì)象鎖,然后當(dāng)前線程處于對(duì)象等待隊(duì)列中阻塞狀態(tài)。,等待? ? ? ? ? ? ? 其他線程喚醒。

? ? (2)void wait(long timeout):同wait()方法,等待timeout毫秒時(shí)間后進(jìn)入隊(duì)列中阻塞狀? ? ? ? ? ? ? ? ? ? ? ? ? ? 態(tài)。

? ? ? (3)void notify():當(dāng)前線程喚醒此對(duì)象等待隊(duì)列中的一個(gè)線程,線程將進(jìn)入就緒狀態(tài)。

? ? ? (4)void notifyAll():當(dāng)前線程喚醒此對(duì)象等待隊(duì)列中的所有線程,線程將進(jìn)入就緒狀? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 態(tài)。

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

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

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