
多線程的基本概念
1.進程
進程是操作系統(tǒng)進行資源分配和調(diào)度的基本單位。
2.線程
線程是進程中的一個執(zhí)行單元,負責(zé)當前進程中程序的執(zhí)行,一個進程中至少有一個線程。
3.多線程
什么是多線程呢?即就是一個程序中有多個線程在同時執(zhí)行。
02
線程的生命周期
java中每個線程都需經(jīng)歷新生、就緒、運行、阻塞和死亡五種狀態(tài),線程從新生到死亡的狀態(tài)變化稱為生命周期。
1.新建狀態(tài)
使用 new Thread 類或其子類建立一個線程對象后,該線程對象就處于新建狀態(tài)。
2.就緒狀態(tài)
調(diào)用了start()方法之后,該線程就進入就緒狀態(tài)(就緒隊列中),等待JVM里線程調(diào)度器的調(diào)度。
3.運行狀態(tài)
執(zhí)行 run(),此時線程便處于運行狀態(tài)。處于運行狀態(tài)的線程最為復(fù)雜,它可以變?yōu)樽枞麪顟B(tài)、就緒狀態(tài)和死亡狀態(tài)。
4.阻塞狀態(tài)
如果一個線程執(zhí)行了sleep(睡眠)、suspend(掛起)等方法,失去所占用資源之后,該線程就從運行狀態(tài)進入阻塞狀態(tài)。
5.死亡狀態(tài)
一個運行狀態(tài)的線程完成任務(wù)或者其他終止條件發(fā)生時,該線程就切換到終止狀態(tài)。
03
線程的調(diào)度策略
線程調(diào)度是指系統(tǒng)為線程分配處理器使用權(quán)的過程。
Java?使用的線程調(diào)度是搶占式調(diào)度,在搶占式調(diào)度下,優(yōu)先級最高的任務(wù)一直執(zhí)行,直到它進入等待或死亡狀態(tài)或更高優(yōu)先級的任務(wù)出現(xiàn),優(yōu)先級高的線程比優(yōu)先級低的線程優(yōu)先執(zhí)行。
在Java多線程環(huán)境中,為保證所有線程的執(zhí)行能按照一定的規(guī)則執(zhí)行,JVM實現(xiàn)了一個線程調(diào)度器,它定義了線程調(diào)度的策略。 在?JVM?中體現(xiàn)為讓可運行池中優(yōu)先級高的線程擁有CPU?使用權(quán)。
04
線程之間的通信與協(xié)作
上面比較清楚的顯示了線程的狀態(tài)流轉(zhuǎn),其實重點主要是掌握運行、阻塞、就緒之間的通信機制。
1.sleep()和yield()和join()
1)sleep()方法作用:讓當前線程睡眠一段時間,期間不會釋放任何持有的鎖。
2) yield()方法作用:讓出該線程的時間片給其它線程。線程調(diào)用了yield()方法,表示放棄當前獲得的CPU時間片,回到就緒狀態(tài)。最后由線程調(diào)度重新選擇就緒狀態(tài)的線程分配CPU資源。
3)join()方法作用:暫停當前線程,等待被調(diào)用線程指向結(jié)束之后再繼續(xù)執(zhí)行。
注意:
1)sleep(long)方法僅釋放CPU使用權(quán),鎖仍然占用。
2)調(diào)用join()的時候,當前線程不會釋放掉鎖。
2.wait()和notify() 方法和notifyAll()方法
1)wait()方法的作用:讓該線程處于等待狀態(tài)。
2)notify()方法的作用:喚醒處于wait的線程。
3)notifyAll()方法的作用:喚醒所有處于wait狀態(tài)的線程。
注意:
1)wait()方法會釋放CPU執(zhí)行權(quán) 和 占有的鎖。
2) 線程調(diào)用wait()方法后,讓該線程處于等待狀態(tài)。進入這個狀態(tài)后,是不能自動喚醒的,必須依靠其他線程調(diào)用notify()或notifyAll()方法才能被喚醒。wait和notify必須配套使用,即必須使用同一把鎖調(diào)用。