為了滿足業(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)。
