靜態代理模式
- 真實對象和代理對象都要實現同一接口
- 代理對象要代理真實角色
- 代理對象可以做很多真實對象做不了的事情
- 真實對象專注做自己的事情
- 它是線程底部的實現原理,你只用
start()
,run()
交給JVM
Lamda表達式
- 目的是爲了避免內部類定義過多
- 其實質是屬於函數式編程的概念
(parms)->expression[表達式]
(parms)->statement[語句]
(parms)->{statements}
- 例
new Thread(()-> System.out.println("代澳旗,加油!")).start();
lamda
表達式的關鍵:函數式接口
函數式接口:只包含一個抽象方法,只有一個!!!
對於函數式接口,我們可以通過lamda
表達式來創建該接口的對象
線程五大狀態
- 五大狀態:創建,就緒,阻塞,運行,死亡
線程常見方法
- 線程停止
- 建議線程正常停止—>利用次數,不建議無限循環
- 建議使用標誌位—>設置一個標誌位
- 不要使用stop或者destory等過時或者JDK不建議使用的方法
- 線程休眠(sleep)
sleep(時間)指定當前線程阻塞的毫秒數
- 存在異常
InterruptedException
sleep
時間到後進入就緒狀態- 可以模擬網絡延時,倒計時
- 每個對象都有一把鎖,sleep不會釋放鎖。
- 線程禮讓(yield)
- 讓當前正在執行的線程暫停,但不阻塞
- 讓線程從運行狀態轉爲就緒狀態
- 讓cpu重新調度,禮讓不一定成功,看CPU心情
- 我本來都要準備運行了,出於禮貌。我重新出來,咱兩重新競爭。所以有可能還是我搶贏了。
- 線程強制執行(join)
- 霸道,強制執行,少使用
- 線程優先級:
- java提供一個線程調度器來監控程序中啓動後進入就緒狀態的所有線程,線程調度器按照優先級決定應該調度哪個線程來執行。
- 線程優先級用數字表示,範圍從1~10
- 獲取優先級:
getPriority().setPriority(int XXX)
- 守護線程:
- 線程分爲用戶線程(如
main線程
)和守護線程(如gc線程
)。正常線程都是用戶線程 - 虛擬機必須確保用戶線程執行完畢
- 虛擬機不用等待用戶線程執行完畢
- 例如: 後臺記錄操作日誌,監控日誌,垃圾回收等。。。
線程同步安全
由於同一進程的多個線程共享同一塊兒存儲空間,在帶來方便的同時,也帶來了訪問衝突問題,爲了保證數據在方法中被訪問時的正確性,在訪問時加入鎖機制
。Synchronized
,當一個線程獲得對象的排它鎖,獨佔資源,其他線程必須等待,使用後釋放鎖即可。
- 一個線程持有鎖會導致其他所需要此鎖的線程掛起。
- 在多線程競爭下,加鎖,釋放鎖會導致比較多的上下文切換,和調度時延,引起性能問題。
- 如果一個優先級高的線程等待一個優先級低的線程釋放鎖,會導致優先級倒置,引起性能問題。
同步方法
- 由於我們可以通過private關鍵字來保證數據對象只能被方法訪問,所以我們需要針對方法提供一套機制,這套機制就是
synchronized
關鍵字,它包括兩種方法:synchronized方法和synchronized塊 synchronized
方法控制對象的訪問,每個對象對應一把鎖,每個synchronized
方法都必須獲得調用該方法對象的鎖才能執行,否則線程會阻塞,方法一旦執行,就獨佔該鎖,直到該方法返回才釋放鎖,後面被阻塞的進程才能獲得這把鎖,繼續執行。缺點就是:若將一個大的方法申明爲synchronized
將會影響效率,鎖的太多,就會浪費資源。
同步塊
- 同步塊:
synchronized(Obj){}
,鎖住的是對象,是需要修改的那個對象。 Obj
稱之爲同步監視器
Obj
可以是任意對象,但是推薦使用共享資源作爲同步監視器。- 同步方法中無需指定同步監視器,因爲同步方法的同步監視器就是
this
.就是這個對象本身,或者是class對象。
- 同步監視器的執行過程
- 第一個線程訪問,鎖定同步監視器,執行其中代碼。
- 第二個線程訪問,發現同步監視器被鎖定,無法訪問。
- 第一個線程訪問完畢,解鎖同步監視器。
- 第二個線程訪問,發現同步監視器沒有鎖了,然後鎖定並訪問。
CopyOnWriteArrayList
- JUC併發包中的類。