java中fail-fast和fail-safe的區別說明

来源:https://www.cnblogs.com/java265/archive/2022/06/01/16334509.html
-Advertisement-
Play Games

synchronized 是java中常見的保證多線程訪問共用資源時的安全的一個關鍵字。很多人在講到synchronized 時都說synchronized 是一把重量級的鎖,那麼synchronized 真的很重麽? synchronized 在jdk 1.6以前(不包括1.6)的確是一把很重的鎖 ...


轉自:

http://www.java265.com/JavaJingYan/202206/16540696313601.html

下文筆者講述fail-fast和fail-safe的區別說明,如下所示

同步修改簡介說明

同步修改(併發修改)指:
當一個或多個線程正在遍歷一個集合Collection
 此時另一個線程修改了這個集合的內容(添加,刪除或修改)

fail-fast機制

fail-fast機制:
   在遍歷一個集合時,當集合結構被修改,會拋出Concurrent Modification Exception
fail-fast:
    會在以下兩種情況下拋出ConcurrentModificationException
  1.單線程環境
    集合被創建後,在遍歷它的過程中修改了結構。
   註意:
     remove()方法會讓expectModcount和modcount相等,所以是不會拋出這個異常

  2.多線程環境
    當一個線程在遍歷這個集合,而另一個線程對這個集合的結構進行了修改 

註意事項:
   迭代器的快速失敗行為無法得到保證,
    因為一般來說,不可能對是否出現不同步併發修改做出任何硬性保證
    快速失敗迭代器會盡最大努力拋出 ConcurrentModificationException
	因此,為提高這類迭代器的正確性而編寫一個依賴於此異常的程式是錯誤的做法:迭代器的快速失敗行為應該僅用於檢測bug

fail-fast機制檢測方法分享

迭代器在遍歷過程中是直接訪問內部數據的
因此內部的數據在遍歷的過程中無法被修改
為了保證不被修改,迭代器內部維護了一個標記"mode",
當集合結構改變(添加刪除或者修改)
標記"mode"會被修改,而迭代器每次的hasNext()和next()方法都會檢查該"mode"是否被改變
當檢測到被修改時,拋出Concurrent Modification Exception

下麵看看ArrayList迭代器部分的源碼
private class Itr implements Iterator<E> {
        int cursor;
        int lastRet = -1;
        int expectedModCount = ArrayList.this.modCount;
 
        public boolean hasNext() {
            return (this.cursor != ArrayList.this.size);
        }
 
        public E next() {
            checkForComodification();
            /** 省略此處代碼 */
        }
 
        public void remove() {
            if (this.lastRet < 0)
                throw new IllegalStateException();
            checkForComodification();
            /** 省略此處代碼 */
        }
 
        final void checkForComodification() {
            if (ArrayList.this.modCount == this.expectedModCount)
                return;
            throw new ConcurrentModificationException();
        }
    }

 

fail-safe機制

fail-safe任何對集合結構的修改都會在一個複製的集合上進行修改,因此不會拋出ConcurrentModificationException
 fail-safe機制有兩個問題
   1.需要複製集合,產生大量的無效對象,開銷大
   2.無法保證讀取的數據是目前原始數據結構中的數據

fail-fast和fail-safe示例

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
 
public class FailFastExample
{
    public static void main(String[] args)
    {
        Map<String,String> map = new HashMap<String,String>();
        map.put("test", "test");
        map.put("test2", "test2");
        map.put("test3","test3");
        
        Iterator iterator = map.keySet().iterator();
        
        while (iterator.hasNext())
        {
            System.out.println(map.get(iterator.next()));
            map.put("test5", "test555");
        }
        
    }
    
}

-----運行以上代碼,將輸出以下信息----- 
Exception in thread "main" java.util.ConcurrentModificationException
        at java.util.HashMap$HashIterator.nextEntry(Unknown Source)
        at java.util.HashMap$KeyIterator.next(Unknown Source)
        at FailFastExample.main(FailFastExample.java:20)


import java.util.concurrent.ConcurrentHashMap;
import java.util.Iterator;
public class FailSafeExample
{
    public static void main(String[] args)
    {
        ConcurrentHashMap<String,String> map = 
                               new ConcurrentHashMap<String,String>();
        map.put("test", "test");
        map.put("test2", "test2");
        map.put("test3","test3");
        
        Iterator iterator = map.keySet().iterator();
        
        while (iterator.hasNext())
        {
            System.out.println(map.get(iterator.next()));
            map.put("test5", "test5555");
        }
        
    }
    
}

輸出
test
test2
test3

 

fail-fast和fail-safe的區別

  Fail Fast Iterator Fail Safe Iterator
Throw ConcurrentModification Exception yes no
Clone object no yes
Memory Overhead no yes
HashMap,Vector,ArrayList,HashSet CopyOnWriteArrayList, ConcurrentHashMap
版權聲明

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 相關示例代碼 WITH sqlt AS (SELECT a.PlaceCode, b.AcupointName FROM ITEM_Place_Correlation a LEFT JOIN ITEM_Acupoint b ON a.AcupointCode = b.AcupointCode AND ...
  • 事務隔離級別 事務併發可能出現的問題 臟寫 事務之間對增刪改互相影響 臟讀 事務之間讀取其他未提交事務的數據 不可重覆讀 一個事務在多次執行一個select讀到的數據前後不相同。因為被別的未提交事務修改,刪除數據或數據被更新被當前事務讀取到了。 幻讀 一個事務在第一次讀取正常數據,第二次讀取到其他未 ...
  • undo日誌 前面學習了redo日誌,redo日誌保證的是崩潰時事務持久性。我們可以從redo日誌恢復到系統崩潰以前。 undo日誌就是為了保證事務回滾時事務所作所為都能回到事務執行前。保證了事務的原子性。redo把我們做增刪改之前的狀態記錄下來,幫助MySQL回滾到事務執行之前的樣子。 這篇文章了 ...
  • 隨著短視頻時代的到來,音視頻剪輯應用不斷增加,市場競爭愈發激烈,如何為用戶提供差異化剪輯功能和優質的音頻處理體驗,已成為行業新的挑戰。 “音頻音樂剪輯“是武漢網冪科技開發的一款手機音頻剪輯應用,支持音樂剪輯、音頻提取、伴奏人聲提取、格式轉換、手機鈴聲製作、拼接、變速、混音、錄音、降噪等功能。為了給用 ...
  • 該項目是學習Nest.js框架所得,前端基於Vue.js + Vuex + VueRouter + ElementUI + SCSS,後端基於Node.js + TypeScript + Nest.js + MySQL + TypeORM。 ...
  • 思路:通過註冊表註冊自定義URL協議執行bat腳本,將文件路徑作為參數傳入 環境:win10 前置問題與條件 問題1:可以從瀏覽器直接打開可執行文件嗎? 答:不能。其實可以通過 ActiveXObject 實現軟體直接打開,但是它是不安全的,並且現在被大多數現代瀏覽器禁止,只能在 ie 使用。而通過 ...
  • 簡單介紹一下,我的 web 前端開發技術選擇。我更偏向於使用 jQuery 及其插件、CSS3、HTML5。不喜歡 mvvm 之類的技術。 ...
  • 近幾年國內外聲名鵲起的Rust編程語言,聲名遠播,影響力巨大,到底是什麼讓它如此強大?本文適合作為一篇初級入門的文章。本文的優勢是通過一個常見的例子作為線索,引出Rust的一些重要理念或者說特性,通過這些特性深刻體會Rust的魅力。 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...