Java多線程(lambda表達式)
目錄
線程創建
繼承Thread類
- 自定義線程類繼承Thread類
- 重寫run()方法,編寫線程執行體
- 創建線程對象,調用start()方法啟動線程
實現Rannable接口
由於java單繼承的局限性,推薦使用此方法
- 定義MyRunnable類實現Runnable接口
- 實現run()方法,編寫線程執行體
- 創建線程對象,通過線程對象調用start方法(靜態代理)
new Thread(MyRunnable).start();
實現Callable接口
-
實現Callable接口,需要返回值類型
-
重寫call方法,需要拋出異常
-
創建目標對象
-
創建執行服務:
ExecutorService ser = Executors.newFixedTreadPool(nThreads);
-
提交執行:
Future<Boolean> result = ser.submit(MyCallable);
-
獲取結果
boolean r = result.get();
-
關閉服務
ser.shutdownNow();
優點
- 可以提供返回值
- 可以拋出異常
靜態代理模式
- 真實對象和代理對象實現同一個接口
- 代理對象要代理真實對象
好處:
- 代理對象可以做很多真實對象做不了的事情
- 真實對象專注做自己的事情
new Thread(() -> {...}).start();
Lambda表達式
-
函數式編程
-
函數式接口
- 只包含唯一一個抽象方法的接口
- 使用lambda表達式來創建函數式接口的對象
-
(參數) -> 表達式\語句\代碼塊
- 多個語句用{}
- 參數可以去掉類型,要去掉都去掉
- 單個參數可以省略括號
線程狀態
- 創建狀態
- 就緒狀態
- 阻塞狀態
- 運行狀態
- 死亡狀態
狀態觀測
- Thead.State state = thread.getState()
- NEW:創建狀態
- RUNNABLE:運行狀態
- BLOCKED:阻塞,等待監視器鎖定
- WAITTING:阻塞,等待另一個線程執行動作
- TIMEED_WAITTING:阻塞,等待另一個線程執行動作達到指定時間
- TERMINATED
線程方法
線程停止
- 建議使用flag讓線程自己停下來
private boolean flag = true;
@Override
public void run(){
while(flag){
...
}
}
public void stop(){
this.flag = false;
}
線程休眠sleep
- 指定線程阻塞的毫秒數
- 存在異常InterruptedException
- 時間到后線程進入就緒狀態
- 不會釋放線程鎖
線程禮讓yield
- 讓當前正在執行的線程暫停,但不阻塞
- 將線程從運行狀態轉為就緒狀態
- 禮讓不一定成功
線程阻塞join
- 等待該線程執行完后,再執行其他線程
- 當前線程阻塞
線程優先級setPriority
- 范圍1~10
- Tread.MIN_PRIORITY = 1;
- Tread.Max_PRIORITY = 1;
- Tread.NORM_PRIORITY = 5;
守護線程setDaemon
- 線程分為用戶線程和守護線程
- 虛擬機必須確保用戶線程執行完畢
- 虛擬機不用等待守護線程執行完畢
- 如:后台記錄操作日志、監控內存、垃圾回收等
線程同步
-
並發:多個線程同時操作同一個對象
-
同時訪問時,進入對象的等待池
-
鎖機制:synchronized方法和synchronized塊
同步塊
- synchronized(Obj){ }
- Obj稱為同步監視器
- 同步監視器可以是任何對象,推薦使用共享資源作為同步監視器
- 同步方法中的同步監視器就是this
- Obj得是同一個實例,才能鎖住
死鎖
- 多個線程互相等待對方釋放資源
- 某一個同步塊同時擁有兩個以上對象的鎖時,就可能會發生死鎖
死鎖產生的四個條件
- 互斥條件:一個資源每次只能被一個進程使用
- 請求與保持條件:一個進程因請求資源而阻塞時,對已獲得的資源保持不放
- 不剝奪條件:進程已獲得的資源,在未使用完之前,不能強行剝奪
- 循環等待的條件:若干進程之間形成一種頭尾相接的循環等待資源關系
Lock鎖
- JDK5.0開始,通過顯式定義同步鎖對象來實現同步
- 常用Lock接口的實現類ReentrantLock(可重入鎖)
private final ReentrantLock lock = new ReentrantLock();
lock.lock();
lock.unlock();
線程通信
在同步方法或同步代碼塊中使用:
- wait():一直等待,會釋放鎖
- wait(long timeout):等待指定毫秒數
- notify():喚醒一個處於等待狀態的線程
- notifyAll():喚醒同一個對象上所有等待的線程
線程池
-
提前創建好多個線程,放入線程池中,使用時直接獲取,使用完放回池中。
-
ExecutorService:線程池接口,常見子類ThreadPoolExecutor
- void execute(Runnable command)
-
Future submit(Callable task): - void shutdown()
-
Executors:工具類、線程池的工廠類,用於創建並返回不同類型的線程池