多線程的基本概念
1.進(jìn)程
進(jìn)程是操作系統(tǒng)進(jìn)行資源分配和調(diào)度的基本單位更卒。
2.線程
線程是進(jìn)程中的一個執(zhí)行單元,負(fù)責(zé)當(dāng)前進(jìn)程中程序的執(zhí)行稚照,一個進(jìn)程中至少有一個線程蹂空。
3.多線程
什么是多線程呢?即就是一個程序中有多個線程在同時執(zhí)行锐锣。
02
線程的生命周期
java中每個線程都需經(jīng)歷新生腌闯、就緒、運行雕憔、阻塞和死亡五種狀態(tài),線程從新生到死亡的狀態(tài)變化稱為生命周期糖声。
1.新建狀態(tài)
使用 new Thread 類或其子類建立一個線程對象后斤彼,該線程對象就處于新建狀態(tài)分瘦。
2.就緒狀態(tài)
調(diào)用了start()方法之后,該線程就進(jìn)入就緒狀態(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)進(jìn)入阻塞狀態(tài)鬼雀。
5.死亡狀態(tài)
一個運行狀態(tài)的線程完成任務(wù)或者其他終止條件發(fā)生時,該線程就切換到終止?fàn)顟B(tài)蛙吏。
03
線程的調(diào)度策略
線程調(diào)度是指系統(tǒng)為線程分配處理器使用權(quán)的過程源哩。
Java?使用的線程調(diào)度是搶占式調(diào)度,在搶占式調(diào)度下鸦做,優(yōu)先級最高的任務(wù)一直執(zhí)行励烦,直到它進(jìn)入等待或死亡狀態(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)矢炼,其實重點主要是掌握運行系瓢、阻塞、就緒之間的通信機(jī)制句灌。
1.sleep()和yield()和join()
1)sleep()方法作用:讓當(dāng)前線程睡眠一段時間夷陋,期間不會釋放任何持有的鎖。
2) yield()方法作用:讓出該線程的時間片給其它線程胰锌。線程調(diào)用了yield()方法骗绕,表示放棄當(dāng)前獲得的CPU時間片,回到就緒狀態(tài)资昧。最后由線程調(diào)度重新選擇就緒狀態(tài)的線程分配CPU資源酬土。
3)join()方法作用:暫停當(dāng)前線程,等待被調(diào)用線程指向結(jié)束之后再繼續(xù)執(zhí)行格带。
注意:
1)sleep(long)方法僅釋放CPU使用權(quán)撤缴,鎖仍然占用刹枉。
2)調(diào)用join()的時候,當(dāng)前線程不會釋放掉鎖屈呕。
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)嗽桩。進(jìn)入這個狀態(tài)后岳守,是不能自動喚醒的,必須依靠其他線程調(diào)用notify()或notifyAll()方法才能被喚醒涤躲。wait和notify必須配套使用棺耍,即必須使用同一把鎖調(diào)用。