Java多線程(lambda表達式)


Java多線程(lambda表達式)

線程創建

繼承Thread類

  • 自定義線程類繼承Thread類
  • 重寫run()方法,編寫線程執行體
  • 創建線程對象,調用start()方法啟動線程

實現Rannable接口

由於java單繼承的局限性,推薦使用此方法

  • 定義MyRunnable類實現Runnable接口
  • 實現run()方法,編寫線程執行體
  • 創建線程對象,通過線程對象調用start方法(靜態代理)
new Thread(MyRunnable).start();

實現Callable接口

  1. 實現Callable接口,需要返回值類型

  2. 重寫call方法,需要拋出異常

  3. 創建目標對象

  4. 創建執行服務:

    ExecutorService ser = Executors.newFixedTreadPool(nThreads);
    
  5. 提交執行:

    Future<Boolean> result = ser.submit(MyCallable);
    
  6. 獲取結果

    boolean r = result.get();
    
  7. 關閉服務

    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得是同一個實例,才能鎖住

死鎖

  • 多個線程互相等待對方釋放資源
  • 某一個同步塊同時擁有兩個以上對象的鎖時,就可能會發生死鎖

死鎖產生的四個條件

  1. 互斥條件:一個資源每次只能被一個進程使用
  2. 請求與保持條件:一個進程因請求資源而阻塞時,對已獲得的資源保持不放
  3. 不剝奪條件:進程已獲得的資源,在未使用完之前,不能強行剝奪
  4. 循環等待的條件:若干進程之間形成一種頭尾相接的循環等待資源關系

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:工具類、線程池的工廠類,用於創建並返回不同類型的線程池


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM