HashMap的fail-fast机制

1.1 HashMap的fail-fast机制

代码展示

        /**
         * HashMap的一个内部临时计数变量,用于HashIterator中快速失败
         */
        transient int modCount;
    
 abstract class HashIterator {
       Node<K,V> next;        // next entry to return
       Node<K,V> current;     // current entry
       int expectedModCount;  // for fast-fail
       int index;             // current slot

       HashIterator() {
           expectedModCount = modCount;
           Node<K,V>[] t = table;
           current = next = null;
           index = 0;
           if (t != null && size > 0) { // advance to first entry
               do {} while (index < t.length && (next = t[index++]) == null);
           }
       }

       public final boolean hasNext() {}

       final Node<K,V> nextNode() {}

       public final void remove() {}
   }


在这里插入图片描述
我们知道 java.util.HashMap 不是线程安全的,因此如果在使用迭代器的过程中有其他线程对Map做了修改,那
将抛出 ConcurrentModificationException,这就是所谓 fail-fast 策略。

fail-fast 机制是 java 集合(Collection)中的一种错误机制。 当多个线程对同一个集合的内容进行操作时,就可能
会产生 fail-fast 事件。
例如:当某一个线程 A 通过 iterator去遍历某集合的过程中,若该集合的内容被其他线程所改变了;那么线程 A
访问集合时,就会抛出 ConcurrentModificationException 异常,产生 fail-fast 事件。
这一策略在源码中的实现是通过 modCount 域,modCount 顾名思义就是修改次数,对 HashMap 内容(其他集合也会有,例如 ArrayList)的修改都将增加这个值,那么在迭代器初始化过程中会将这个值赋给迭代器的 expectedModCount。

在这里插入图片描述

在迭代过程中,迭代器首先会获得几个修改个数,判断 modCount 跟 expectedModCount 是否相等,如果不相等就表示已经有其他线程修改了Map ,就会抛出ConcurrentModificationException异常。如果必须在迭代过程中修改元素,那么可以使用HashIterator的remove方法,对元素进行操作。那么问题来了,迭代器的remove方法会不会对原集合的元素个数做出修改呢?我们一起看看源码实现。

 public final void remove() {
     Node<K,V> p = current;
     if (p == null)
         throw new IllegalStateException();
     if (modCount != expectedModCount)
         throw new ConcurrentModificationException();
     current = null;
     K key = p.key;
     removeNode(hash(key), key, null, false, false);// 调用原集合的removeNode方法,即原集合也会修改
     expectedModCount = modCount;
 }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值