第一章-併發編程的挑戰

併發編程目的是讓程序運行的更快。並非啓動更多的線程就能讓程序最大限度的執併發執行。併發編程時,若是想經過多線程執行任務讓程序執行的更快,會有不少挑戰。好比:算法

  • 上下文切換問題
  • 死鎖問題
  • 受限於軟件和硬件資源

1.1 - 上下文切換

單核處理器也能支持多線程執行代碼。CPU給每一個線程分配cpu時間片來實現這個機制。時間片是CPU分配給每一個線程的執行時間,時間很是短(通常幾十ms),因此經過不停的切換線程執行,因此感受多線程是同時執行的。編程

上下文切換:CPU經過時間片分配算法來循環執行任務。當前任務執行一個時間片,保存這個任務的狀態,而後切換到下一個任務。
保存狀態是爲了下次切換到這個任務的時候,能夠再加載這個任務的狀態。任務從保存到再加載的過程就是一次上下文切換。

1.1.1 - 測試上下文切換次數和時長

經過工具測量上下文切換帶來的消耗:多線程

  1. Lmbench3測量上下文切換時長
  2. vmstat測量上下文切換次數 vmstat 1

1.1.2 - 減小上下文切換

方法有:併發

  1. 無鎖併發編程
    多線程競爭鎖,會引發上下文切換。因此多線程處理數據時,可使用其餘辦法來避免使用鎖。好比,id按照hash算法取模分段,不一樣的線程處理 不一樣的數據。工具

  2. cas算法
    Java的Atomic包使用cas算法來更新數據,不須要加鎖測試

  3. 使用最少線程 避免建立不須要的線程。好比任務少,但建立了不少線程來處理。形成大量線程都處於等待狀態。線程

  4. 協程 在單線程裏實現多任務調度,在單線程裏維持多個任務間的切換code

1.2 - 死鎖

避免死鎖的幾個常見辦法:協程

  1. 避免在一個線程同時獲取多個鎖
  2. 避免一個線程在鎖內同時佔用多個資源,儘可能保證一個鎖只佔用一個資源
  3. 嘗試使用定時鎖,使用lock.tryLock(timeout)來替代內部鎖機制
相關文章
相關標籤/搜索