努力使失敗保持原子性(64)
阿新 • • 發佈:2018-12-10
失敗的原子呼叫應該使得物件保持在被呼叫之前的狀態,所謂:失敗原子性
- 幾種途徑實現:
- 設計一個不可變物件,其失敗原子性是顯然的
- 對於可變引數,執行前檢查引數有效性
- 避免執行一半報錯,後續無法執行導致狀態不一致
- 調整計算順序,使得任何可能失敗的部分,放到狀態修改前,進而獲得原子性
- (不常用)編寫恢復程式碼,攔截操作中的失敗,使物件回滾到原來的狀態
- 主要用於永久性的資料結構
- 在物件的臨時拷貝上做操作,成功後再用臨時拷貝的結果代替物件的內容
- 如果失敗,不影響原有物件的狀態
- 由於是臨時資料,計算過程更加迅速
- Collections.sort 先將輸入列表轉到陣列中,降低排序內迴圈訪問元素的開銷
- 如上程式碼,如果不做檢查size == 0 ,仍然會丟擲異常,
- 但是size 域處於,下標為-1的不一致狀態,其他操作都無法進行
- 別的方法使用時,會丟擲與之不匹配的異常
並非都能做到失敗原子性:
- 比如倆執行緒同時操作一個物件,就可能會導致不一致狀態:ConcurrentModificationException
- 錯誤(相對於異常)通常是不可恢復的,沒必要保持失敗一致性
一般,方法規範的一部分,任何異常都應該使得物件保持在方法呼叫之前的狀態
- 如果違反該規範,物件將會處於什麼狀態
- 大部分api 沒有做到這一點