1.?多線程:
(1)?多線程,同一時間,做多件事情
(2)?同一個時間點,只能做一件事情
(3)?同步與異步
2.?Java中的多線程:
從main方法入口,啟動Main線程,兩種多線程實現(xiàn)方式
(1)?繼承Thread類
(2)實現(xiàn)Runnable接口,這個是推薦使用
原因:
(1)?Java是單繼承,可以實現(xiàn)多個接口
(2)?Runnable本身是任務的概念
3.?進程與線程:
(1)?進程:CPU分配資源的最小單位
(2)?線程:本身不占用資源,但是要消耗進程分配的資源
(3)?一個應用進程有多個進程,一個進程有多個線程
4.?生命周期
(1)?狀態(tài):
a.?新建狀態(tài)(New):創(chuàng)建一個線程對象
b.就緒狀態(tài)(Runnable):線程對象創(chuàng)建后,其他線程調(diào)用該對象的start()方法。該狀態(tài)的線程位于可運行線程池中,變得可運行,等待獲取CPU的使用權(quán)
c.運行狀態(tài)(Running):就緒狀態(tài)的線程獲取CPU,執(zhí)行程序代碼
d.?阻塞狀態(tài)(Blocked):阻塞狀態(tài)是線程因為某種原因放棄CPU使用權(quán),暫時停止運行。直到線程進入就緒狀態(tài),才有機會轉(zhuǎn)到運行狀態(tài)
e.等待阻塞:運行的線程執(zhí)行wait()方法,JVM會把該線程放入等待池中(wait會釋放持有的鎖)
f.同步阻塞:運行的線程在獲取對象的同步鎖時,若該同步鎖被別的線程占用,則JVM會把該線程放入鎖池中
g.其他阻塞:運行的線程執(zhí)行sleep()或join()方法,或者發(fā)出I/O請求時,JVM會把該線程置為阻塞狀態(tài)。當sleep()狀態(tài)超時、join()等待線程終止或者超時、或者I/O處理完畢時,線程重新轉(zhuǎn)入就緒狀態(tài)。
h.死亡狀態(tài)(Dead):線程執(zhí)行完了或者因異常退出run()方法,該線程結(jié)束生命周期
(2)?常用方法
a.?靜態(tài)方法:sleep()\yield()
b.?普通方法:join()、wait()、notify()、notifyAll()、setPriority()、currentThread()
5.?線程同步和線程通信
(1)?線程同步:將操作共享數(shù)據(jù)的代碼作為一個整體,同一時間只允許一個線程執(zhí)行,執(zhí)行過程中其他線程不能參與執(zhí)行。
目的:防止多個線程訪問一個數(shù)據(jù)對象時,對數(shù)據(jù)造成的破壞
①?同步方法:與有可能發(fā)生資源共享的方法添加synchronized關(guān)鍵字修飾
Public synchronized void run(){}
②?同步代碼塊:有可能發(fā)生資源共競的代碼塊,給它加一個同步鎖,即在代碼塊前添加synchronized來修飾
Synchronized (obj){}
③同步鎖(Lock):Lock對象與資源對象同樣具有一對一的關(guān)系
Class XX{
//顯示定義Lock同步鎖對象,此對象與共享資源具有一對一關(guān)系
Private final Lock lock=new ReentrantLock();
Public void mx{
//加鎖
Lock.lock();
//需要進行線程安全同步的代碼
//釋放同步鎖
Lock.unlock();
}
}
(2)?線程通信:
①?Wait():導致當前線程等待并使其進入到等待阻塞狀態(tài)。知道其他線程調(diào)用該同步鎖對象的notify()或notifyAll()方法來喚醒此線程
②?Notify():喚醒在此同步鎖對象上等待的單個線程,如果有多個線程都在此同步鎖對象等待,則會任意選擇其中某個線程進行喚醒操作,只有當前線程放棄對同步鎖對象的鎖定,才可能執(zhí)行被喚醒的線程.
③?notifyAll():喚醒在此同步鎖對象上等待的所有線程,只有當前線程放棄對同步鎖對象的鎖定,才可能執(zhí)行被喚醒的線程
這三個方法都是Object中的方法,必須與synchronized一起使用
Wait()與sleep()區(qū)別:
1)?wait()是Object類的方法,sleep()是Thread類的靜態(tài)方法
2)?Wait()必須與synchronized一起使用,sleep()則不用
3)?Wait()完,線程進入等待隊列,而sleep()完,線程會進入阻塞隊列
4)?Wait()方法會釋放同步鎖,而sleep()則不會釋放同步鎖
5)都會拋出InterruptedException