1. 程式人生 > >努力使失敗保持原子性(64)

努力使失敗保持原子性(64)

失敗的原子呼叫應該使得物件保持在被呼叫之前的狀態,所謂:失敗原子性

  • 幾種途徑實現:
    • 設計一個不可變物件,其失敗原子性是顯然的
    • 對於可變引數,執行前檢查引數有效性
      • 避免執行一半報錯,後續無法執行導致狀態不一致
      • 調整計算順序,使得任何可能失敗的部分,放到狀態修改前,進而獲得原子性
    • (不常用)編寫恢復程式碼,攔截操作中的失敗,使物件回滾到原來的狀態
      • 主要用於永久性的資料結構
    • 在物件的臨時拷貝上做操作,成功後再用臨時拷貝的結果代替物件的內容
      • 如果失敗,不影響原有物件的狀態
      • 由於是臨時資料,計算過程更加迅速
        • Collections.sort 先將輸入列表轉到陣列中,降低排序內迴圈訪問元素的開銷

  • 如上程式碼,如果不做檢查size == 0 ,仍然會丟擲異常,
  • 但是size 域處於,下標為-1的不一致狀態,其他操作都無法進行
  • 別的方法使用時,會丟擲與之不匹配的異常

並非都能做到失敗原子性:

  • 比如倆執行緒同時操作一個物件,就可能會導致不一致狀態:ConcurrentModificationException
  • 錯誤(相對於異常)通常是不可恢復的,沒必要保持失敗一致性

一般,方法規範的一部分,任何異常都應該使得物件保持在方法呼叫之前的狀態

  • 如果違反該規範,物件將會處於什麼狀態
  • 大部分api 沒有做到這一點