色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

單線程是否會引起 fail-fast機制

科技綠洲 ? 來源:Java技術指北 ? 作者:Java技術指北 ? 2023-10-10 16:31 ? 次閱讀

fail-fast 是什么

引用百度百科的數據:

fail-fast 機制是 java 集合 (Collection) 中的一種錯誤機制。當多個線程對同一個集合的內容進行操作時,就可能會產生 fail-fast 事件。例如:當某一個線程 A 通過 iterator 去遍歷某集合的過程中,若該集合的內容被其他線程所改變了;那么線程 A 訪問集合時,就會拋出 ConcurrentModificationException 異常,產生 fail-fast 事件。

多線程?并發修改?才會引起 fail-fast 機制保護程序?小 B 覺得這個答案沒有說全,面試官說了單線程也會引起 fail-fast 機制。那么關于單線程是否會引起 fail-fast 機制,百度百科說的對還是面試官說的對,寫一個 demo 就清楚了。

import java.util.ArrayList;
import java.util.List;

public class FastFailTest {

    public static void main(String[] args) {
        List< String > list = new ArrayList< String >();

        list.add("張三");
        list.add("李四");
        list.add("王五");
        list.add("趙六");

        for(String s : list) {
            if(s.equals("趙六")) {
                list.remove(s);
                System.out.println(list.toString());
            }
        }
    }
}

從下圖的運行結果來看,list 已經完成了對 [趙六] 的 remove,說明并不是 remove 引發的問題,仔細查看異常原因:是在 ArrayList 的內部 Itr.checkForComodification() 方法出現的 ConcurrentModificationException 異常。小 B 感概了一句:網上資料不可盡信,動手實戰才能出真知。

圖片

原理

將異常定位到報錯的 ArrayList.java:911 行。

final void checkForComodification() {
    if (modCount != expectedModCount)
        throw new ConcurrentModificationException();
}

可以看到這個方法 checkForComodification 對 modCount 和 expectedModCount 進行了比較,如果不相同就拋出異常。modCount 和 expectedModCount 分別又是什么呢?remove 方法中不是修改了 modCount 就是修改了 expectedModCount。

modCount 被定義在 ArrayList 的父類 AbstractList 中,每一次調用 Add、Remove、Clear 等方法 modCount 就被 +1,可以說明這個變量的作用就是記錄了 ArrayList 實際被修改的次數。

ArrayList 的 foreach 方法是用迭代器 Iterator 實現的,Iterator 在 ArrayList 中有一個實現類:Itr,它的成員變量 expectedModCount 在初始化的時候被賦值了 modCount。所以當 ArrayList 調用 remove 刪除元素時,modCount 被 +1,此時不等于 expectedModCount,在 foreach 試圖將局部變量 s 交接給下一個元素的時候,就出現了 ConcurrentModificationException 異常。

圖片

避免

經過分析,ConcurrentModificationException 是由于 modCount 和 expectedModCount 不一樣導致的。

那么如何避免在循環的時候 add、remove 元素不拋出異常呢?

for 循環

使用普通的 for 循環,這樣就可以不經過 Itr 內部類了。

List< String > list = new ArrayList< String >();

list.add("張三");
list.add("李四");
list.add("王五");
list.add("趙六");

for( int i = 0; i < list.size(); i++) {
    String s = list.get(i);
    if(s.equals("王五")) {
        list.remove(s);
        System.out.println(list.toString());
    }
}

示例結果是 [張三, 李四, 趙六] 沒有出現異常。但是移除元素后面的索引已經被改變了。

迭代器 Iterator

直接使用迭代器 Iterator 中的方法,在它的remove 方法中顯示的將 expectedModCount 賦值成 modCount。

//Itr.remove()
public void remove() {
    if (lastRet < 0)
        throw new IllegalStateException();
    checkForComodification();

    try {
        ArrayList.this.remove(lastRet);
        cursor = lastRet;
        lastRet = -1;
        expectedModCount = modCount;
    } catch (IndexOutOfBoundsException ex) {
        throw new ConcurrentModificationException();
    }
}

定義一個迭代器局部變量,使用 hasNext() 方法控制 while 循環。

List< String > list = new ArrayList< String >();

list.add("張三");
list.add("李四");
list.add("王五");
list.add("趙六");

Iterator< String > iterator = list.iterator();
while (iterator.hasNext()) {
    String s = iterator.next();
    if(s.equals("王五")) {
        iterator.remove();
        System.out.println(list.toString());
    }
}

CopyOnWriteArrayList

CopyOnWriteArrayList 是 java 并發包 java.util.concurrent 下面的類。它在操作 add、remove 元素時,先將原來的元素數組拷貝一份成為新的數組,在新數組上面做元素操作,修改完成后,將 CopyOnWriteArrayList 中數組的引用指向了新數組。

List< String > list = new CopyOnWriteArrayList< String >();

list.add("張三");
list.add("李四");
list.add("王五");
list.add("趙六");

for(String s : list) {
    if(s.equals("李四")) {
        list.remove(s);
        System.out.println(list.toString());
    }
}

總結

fail-fast 機制就是不允許程序員不管是在單線程還是多線程環境中遍歷集合的時候順便還操作集合里面的元素。

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • JAVA
    +關注

    關注

    19

    文章

    2966

    瀏覽量

    104702
  • 程序
    +關注

    關注

    117

    文章

    3785

    瀏覽量

    81004
  • 單線程
    +關注

    關注

    0

    文章

    17

    瀏覽量

    1771
收藏 人收藏

    評論

    相關推薦

    單線程的雙任務調度

    STM32是單線程的,通信協議層和應用功能層的耦合性比較低,如果獨立運行,提高效率不少,主要實現的方法有哪些呢?
    發表于 01-10 10:15

    單線程SRAM靜態內存使用

    概述本篇只要介紹這么使用STM32CubeMx工具添加RT-Thread操作系統組件,碼代碼的IDE是keil。介紹單線程SRAM靜態內存使用。如果還不知道,這么使用STM32CubeMx工具添加
    發表于 08-24 06:57

    一種單線程編程思路簡析

    事件驅動?邏輯控制?基于回調的事件驅動或者邏輯控制特點代碼接口實現用法基于回調的事件驅動或者邏輯控制本文提供了一種單線程編程思路,并簡單實現了該思路。受PLC編程線圈和觸點概念的啟發。將程序抽象理解
    發表于 02-16 06:58

    LabWindows_CVI多線程技術的應用研究

    分析了線程與進程的關系,研究了LabWindows/CVI多線程技術運行機制及其數據保護機制,對利用異步定時器實現的多線程軟件與傳統
    發表于 08-29 14:53 ?68次下載
    LabWindows_CVI多<b class='flag-5'>線程</b>技術的應用研究

    線程好還是單線程好?單線程和多線程的區別 優缺點分析

    摘要:如今單線程與多線程已經得到普遍運用,那么到底多線程好還是單線程好呢?單線程和多線程的區別又
    發表于 12-08 09:33 ?8.1w次閱讀

    從I/O的阻塞與非阻塞、I/O處理的單線程與多線程角度探討服務器模型

    這里探討的服務器模型主要指的是服務器端對I/O的處理模型。從不同維度可以有不同的分類,這里從I/O的阻塞與非阻塞、I/O處理的單線程與多線程角度探討服務器模型。
    的頭像 發表于 01-08 16:13 ?6998次閱讀

    Intel處理器占據CPU單線程性能前17位 酷睿i9-9900KS仍穩居榜首

    目前,PassMark的CPU單線程性能圖表仍然由Intel芯片主導。在AMD的Ryzen 9 PRO 3900前面,總共有17個Intel處理器占據了主導地位。
    發表于 04-09 14:39 ?2738次閱讀
    Intel處理器占據CPU<b class='flag-5'>單線程</b>性能前17位 酷睿i9-9900KS仍穩居榜首

    實現Java多線程爬蟲的兩點

    在我們調試爬蟲程序的時候,單線程爬蟲沒什么問題,但是當我們在線上環境使用單線程爬蟲程序去采集網頁時,單線程就暴露出了兩個致命的問題:
    的頭像 發表于 05-05 21:25 ?1958次閱讀
    實現Java多<b class='flag-5'>線程</b>爬蟲的兩點

    這款16核怪物在單線程和多線程性能方面均躍居主流處理器榜首

    盡管AMD一段時間以來一直在主流芯片中注入更多的內核,但在單線程性能方面,這家芯片制造商的產品還不能與Intel的產品相提并論。如果這些PassMark號碼準確無誤,那么Zen 3似乎終于可以輕而易舉地獲得AMD的青睞。
    的頭像 發表于 10-28 15:24 ?2091次閱讀

    單線程也能開發異步任務?ACE JS框架到底是如何做到的

    ,用JS語言開發是否會導致硬件資源無法充分利用的情況呢? 本文給大家介紹“ACE JS的單線程異步機制”就是解決這個問題的。然而,說到 “單線程”與“異步”,大家可能會比較疑惑,因為
    的頭像 發表于 08-13 17:16 ?2032次閱讀
    <b class='flag-5'>單線程</b>也能開發異步任務?ACE JS框架到底是如何做到的

    JVM的垃圾機制是如何工作的呢?

    單線程收集器,“單線程” 的意義并不僅僅說明它只會使用一個 CPU 或一條收集線程去完成垃圾收集工作,更重要的是在它進行垃圾收集時,必須暫停其他所有的工作線程 , 直到它收集結束。
    的頭像 發表于 02-28 16:08 ?601次閱讀

    Redis為何選擇單線程

    Redis為何選擇單線程? 在Redisv6.0以前,Redis的核心網絡模型選擇用單線程來實現。 核心意思就是,對于一個 DB 來說,CPU 通常不會是瓶頸,因為大多數請求不會是 CPU 密集型
    的頭像 發表于 10-09 10:59 ?378次閱讀

    Go在單線程計算性能上的優勢

    一文中,我們討論了Go在單線程計算性能上的優勢。 現在,考慮這樣的一種場景: 我們需要從某些網址中同步數據并進行計算,保存到本地redis緩存中。 現在,我們可以通過編寫Go Worker的方式
    的頭像 發表于 11-02 11:16 ?480次閱讀
    Go在<b class='flag-5'>單線程</b>計算性能上的優勢

    redis多線程還能保證線程安全嗎

    Redis是一種使用C語言編寫的高性能鍵值存儲系統,它是單線程的,因為使用了多路復用的方式來處理并發請求。這樣的實現方式帶來了很好的性能,但同時也引發了一些線程安全方面的問題。 在Redis中,由于
    的頭像 發表于 12-05 10:28 ?1797次閱讀

    什么是多核多線程?多核多線程如何提高程序的運行效率?

    單線程無法充分利用多核處理器的并行計算能力。
    的頭像 發表于 02-20 10:22 ?1350次閱讀
    主站蜘蛛池模板: 国内精品乱码卡一卡2卡三卡| s8sp视频高清在线播放| 97SE亚洲国产综合在线| 成片免费观看视频大全| 国产在线一区二区AV视频| 快播h网站| 忘忧草研究所 麻豆| 中文亚洲大香伊蕉不卡一区| 擦擦擦在线视频观看| 韩国g奶空姐| 日本免费无码A专区在线观看| 亚洲AV香蕉一区区二区三区蜜桃| 91天仙tv嫩模福利| 国产亚洲精品AAAAAAA片| 男人天堂黄色| 亚洲精品无码成人AAA片| xiah俊秀| 麻豆精品2021最新| 亚洲国产精麻豆| 超碰国产亚洲人人| 久久免费国产视频| 亚洲国产区中文在线观看| 成人免费网址在线| 男女午夜性爽快免费视频不卡 | 一区二区三区四区国产| 古风H啪肉NP文| 全球真实小U女视频合集| 在线亚洲97se| 精品一成人岛国片在线观看| 少女开女包www| 成人无码国产AV免费看直播| 免费毛片a在线观看67194| 在线免费观看毛片网站| 九色PORNY真实丨首页| 亚洲国产在线2020最新| 国产女人喷潮视频免费| 我不卡影院手机在线观看| 疯狂第一次国语| 体育生爆操| 国产成人精品自拍| 思思re热免费精品视频66|