《筆記》之學習高併發

wrinkles21發表於2019-03-25

《筆記》1.學習高併發

讀者,你好!這是我的第一篇Blog,純屬記載學習https://my.oschina.net/hosee/blog/597934高併發知識時候的一些記錄和個人領悟!

高併發就是同一時刻有多個執行緒訪問了同一個資料資源;

常見而說不出口的名詞

  1. 同步 :你得等待上一個請求完成才能在傳送請求;
  2. 非同步 :你傳送請求時不需要等待上一個請求結束;
  3. 並行 :(並肩前行嘛?)兩條生產線上的流水,共同前行,互不影響 (單CPU是無法實現的);
  4. 併發 :一個生產線,一會這個任務執行一下,一會又切換另一個任務執行一會 (多工交替進行);
  5. 臨界區 ,見圖:(個人理解就是:資源佔用區間)
    在這裡插入圖片描述
  6. 死鎖 所有執行緒都處於互相等待的一種靜止狀態;(資源相互競爭/執行緒間相互通訊造成的阻塞)
  7. 活鎖 所有執行緒都在相互交換僅有的資源(部分),造成誰也沒有機會得到所有資源造成阻塞的一種動態
  8. 飢餓 是指執行緒一直得不到所需資源,而得不到執行的狀態;
  • 併發級別的阻塞和非阻塞:
  • 阻塞:當一個執行緒進入臨界區時,其他執行緒都必須等待;
  • 非阻塞:可分為無障礙,無鎖,無等待
    • 無障礙:(最慫的的非阻塞排程,不能確保有競爭是一定能完成操作)
      • 自由進出臨界區
      • 無競爭時,有限步完成操作,儘快釋放
      • 有競爭時,(立馬放棄,回滾資料)
    • 無鎖(可解決無障礙的問題,至少保障所有執行緒都能執行下去 廣泛使用
      • 無障礙的(即包含無障礙的特性)
      • 保證有執行緒可以獲得資源
        無鎖程式碼可以參考連結文中(大佬程式碼就不復制,尊重一下)
    • 無等待(最優狀態,但難以實現)
      • 無鎖的
      • 要求所有執行緒都要在有限步內完成操作即無飢餓的(即使優先順序極低也是可以完成的,不會一直處於等待)

程式&執行緒

  • 執行緒是程式的執行單元
  • 多程式一般不考慮併發,併發通常為多執行緒設計;
  • Jvm將會把Java中的執行緒對映到作業系統的執行緒區;
  • 執行緒啟動:Thread.start()
  • 優雅的執行緒中斷示例:
public void run(){ 
    while(true)
    { 
        if(Thread.currentThread().isInterrupted())
        { 
           System.out.println("Interruted!"); 
           break; 
        } 
        Thread.yield(); 
    } 
}

使用中斷,保證了資料的一致性。

對於可取消的阻塞狀態中的執行緒, 比如等待在這些函式上的執行緒, Thread.sleep(), Object.wait(), Thread.join(), 這個執行緒收到中斷訊號後, 會丟擲InterruptedException, 同時會把中斷狀態置回為false.

對於取消阻塞狀態中的執行緒,可以這樣抒寫程式碼:

public void run(){
    while(true){
        if(Thread.currentThread().isInterrupted()){
            System.out.println("Interruted!");
            break;
        }
        try {
           Thread.sleep(2000);
        } catch (InterruptedException e) {
           System.out.println("Interruted When Sleep");
           //設定中斷狀態,丟擲異常後會清除中斷標記位
           Thread.currentThread().interrupt();
        }
        Thread.yield();
    }
}
  • 執行緒關閉:太暴力不推薦(容易導致資料不同步)Thread.stop()==>直接釋放所有monitor?是我的風格

  • 執行緒中斷:(並非立馬停止,只是將執行緒的.isInterrupted狀態改為true,提醒他接下來你要自己找個合適的時機準備停下來)但實際上並沒有停下來,只是改個狀態而已
    public void Thread.interrupt() // 中斷執行緒
    public boolean Thread.isInterrupted() // 判斷是否被中斷
    public static boolean Thread.interrupted() // 判斷是否被中斷,並清除當前中斷狀態

  • yeild

  • yeild是個native靜態方法,這個方法是想把自己佔有的cpu時間釋放掉,然後和其他執行緒一起競爭(注意yeild的執行緒還是有可能爭奪到cpu,注意與sleep區別)。

  • join

  • 方法的意思是等待其他執行緒結束
    未完待續 >a<
    謝謝觀看,如有理解錯誤的地方,煩請指出 >#<

相關文章