---
# System prepended metadata

title: 平行化
tags: [CleanCode]

---

###### tags: `CleanCode`
<STYLE>
p,li,oi,h3{
font-family:"微軟正黑體";
}
</STYLE>
# 平行化
原則與技巧
* **單一職責原則**：適當劃分與執行緒相關的程式碼與其他程式碼。
* 獨立運行：試著將資料需求劃分成可讓每個執行緒獨立操作的獨立子集合。
* 臨界區域(critical section)：嚴格限制共享資料的數量並縮小其視野(Scope)，盡可能讓同步區塊越簡短越好。使用同步化(synchronized)來保護共享物件的臨界區域。
* 盡量避免**共享**資料：可以考慮讓多執行緒抓取物件的複製版，並使其成為唯獨型態，再由單一執行緒將結果合併。
* 考量系統的關閉行為，諸如：死結、永久等待的問題。
* 頻繁地進行測試：
    * 解決偶發事件的錯誤。
    * 首要確保在非執行緒環境中，程式運作正常。
    * 讓執行緒程式碼是可隨插即用的，如此才能於不同環境下執行它。
    * 在每個可能的部屬環境中，測試執行緒的程式碼。
    * 試圖讓程式碼產生失敗：如，增加wait()、sleep()、yield()和priority()函式。
    
---
Java提供的允許同步的類別：
| 類別 | 敘述 |
| -------- | -------- |
| ConcurrentHashMap | 允許同步存取，支援非安全執行緒的常見複合操作|
| ReentrantLock | 一個在A方法取得，並在B方法中釋放的鎖。|
| Semaphore | 傳統semaphore(號誌)的實作，具有計數功能的鎖。|
| CountDownLatch | 該鎖會先等待指定數量的事件，再釋放給等待這個鎖的執行緒，使他們能購公平地同時啟動。|
※可見java.util.concurrent、java.util.concurrent.atomic、java.util.concurrent.locks
#
#### 非阻礙中斷(nonblicking)
不斷地偵測是否發生修改相同數值的情況。比起使用同步化(synchronized)節省更多效能。因為後者會不段的要求鎖住共享數值。
使用AtomicBoolean、AtomicInteger、AtomicReference等類別。
![](https://i.imgur.com/e19Q7rr.png)

#
#### 當心同步方法間地相依性
:::warning
**避免在一個共享物件上使用超過一個方法**
:::

解決方式：
* **客戶端**的鎖定(不建議)
   客戶端在呼叫方法前，先鎖定伺服器(確保鎖定範圍涵蓋到最後一個呼叫的方法)。
* **伺服器**的鎖定(優先使用)
   在伺服器建立一個鎖定方法，讓客戶端呼叫。此鎖定方法在執行完畢後解鎖。
   *能減少重複的程式碼、減少錯誤的可能性、強制使用單一策略、減少共用變數的視野*
* 適應性伺服器(Adapted Server)
   建立一個中間層，鎖定方式與2相同，但不必修改原本伺服器的程式碼。
        
   程式碼編寫：
   ![](https://i.imgur.com/eXEinbQ.png)
