精华内容
下载资源
问答
  • fast-fail 以及 fast-safe

    2021-08-06 10:14:21
    // 1、父集合操作会导致子集合出现 fast-fail // 2、子集合增删改查会影响父集合 // 3、删除元素利用迭代器 // 4、多线程需要考虑线程安全 // 5、COW 集合的使用可以避免线程安全问题 private static Object ...
    public class TestDemo {
    
        // 1、父集合操作会导致子集合出现 fast-fail
        // 2、子集合增删改查会影响父集合
        // 3、删除元素利用迭代器
        // 4、多线程需要考虑线程安全
        // 5、COW 集合的使用可以避免线程安全问题
        private static Object lock = new Object();
    
        // fast-fail  fast-safe
        public static void main(String[] args) {
    
            List<String> masterList = new ArrayList<>(10);
    
            masterList.add("a");
            masterList.add("b");
            masterList.add("c");
            masterList.add("d");
    
    
            List<String> stringList = masterList.subList(0, 3);
    
            masterList.remove(0);
            masterList.add("ten");
            masterList.clear();
    
    
            System.out.println(stringList);
            stringList.clear();
            System.out.println(stringList);
            System.out.println(masterList);
    
    
            List<String> list = new ArrayList<>(10);
    
            list.add("one");
            list.add("two");
            list.add("three");
    
            for (String s : list) {
                if("two".equals(s)){
                    list.remove(s);
                }
            }
    
            System.out.println(list);
    
            List<String> list1 = new ArrayList<>(10);
    
            list1.add("one");
            list1.add("two");
            list1.add("three");
    
            Iterator<String> iterator = list1.iterator();
    
            while (iterator.hasNext()) {
                synchronized (lock) {
                    String next = iterator.next();
                    if ("one".equals(next)) {
                        iterator.remove();
                    }
                }
            }
    
            System.out.println(list1);
    
    
        }
    
    }
    
    展开全文
  • 主要介绍了Java的迭代器中的fast-fail错误检测机制,需要的朋友可以参考下
  • Fast-fail原理

    2016-03-19 19:26:04
    fast-fail的为何种异常,如果处理


    1 fail-fast简介

    fail-fast 机制是java集合(Collection)中的一种错误机制。 当多个线程对同一个集合的内容进行操作时,就可能会产生 fail-fast 事件。 
    例如:当某一个线程A通过 iterator 去遍历某集合的过程中,若该集合的内容被其他线程所改变了;那么线程A访问集合时,就会抛出 ConcurrentModificationException 异常,产生 fail-fast 事件。

    在详细介绍 fail-fast 机制的原理之前,先通过一个示例来认识 fail-fast 。

    2 fail-fast示例

    示例代码:( FastFailTest.java )

     1 import java.util.*;
     2 import java.util.concurrent.*;
     3 
     4 /*
     5  * @desc java集合中Fast-Fail的测试程序。
     6  *
     7  *   fast-fail事件产生的条件:当多个线程对Collection进行操作时,若其中某一个线程通过iterator去遍历集合时,该集合的内容被其他线程所改变;则会抛出ConcurrentModificationException异常。
     8  *   fast-fail解决办法:通过util.concurrent集合包下的相应类去处理,则不会产生fast-fail事件。
     9  *
    10  *   本例中,分别测试ArrayList和CopyOnWriteArrayList这两种情况。ArrayList会产生fast-fail事件,而CopyOnWriteArrayList不会产生fast-fail事件。
    11  *   (01) 使用ArrayList时,会产生fast-fail事件,抛出ConcurrentModificationException异常;定义如下:
    12  *            private static List<String> list = new ArrayList<String>();
    13  *   (02) 使用时CopyOnWriteArrayList,不会产生fast-fail事件;定义如下:
    14  *            private static List<String> list = new CopyOnWriteArrayList<String>();
    15  *
    16  * @author skywang
    17  */
    18 public class FastFailTest {
    19 
    20     private static List<String> list = new ArrayList<String>();
    21     //private static List<String> list = new CopyOnWriteArrayList<String>();
    22     public static void main(String[] args) {
    23     
    24         // 同时启动两个线程对list进行操作!
    25         new ThreadOne().start();
    26         new ThreadTwo().start();
    27     }
    28 
    29     private static void printAll() {
    30         System.out.println("");
    31 
    32         String value = null;
    33         Iterator iter = list.iterator();
    34         while(iter.hasNext()) {
    35             value = (String)iter.next();
    36             System.out.print(value+", ");
    37         }
    38     }
    39 
    40     /**
    41      * 向list中依次添加0,1,2,3,4,5,每添加一个数之后,就通过printAll()遍历整个list
    42      */
    43     private static class ThreadOne extends Thread {
    44         public void run() {
    45             int i = 0;
    46             while (i<6) {
    47                 list.add(String.valueOf(i));
    48                 printAll();
    49                 i++;
    50             }
    51         }
    52     }
    53 
    54     /**
    55      * 向list中依次添加10,11,12,13,14,15,每添加一个数之后,就通过printAll()遍历整个list
    56      */
    57     private static class ThreadTwo extends Thread {
    58         public void run() {
    59             int i = 10;
    60             while (i<16) {
    61                 list.add(String.valueOf(i));
    62                 printAll();
    63                 i++;
    64             }
    65         }
    66     }
    67 
    68 }
    View Code

    运行结果 : 
    运行该代码,抛出异常java.util.ConcurrentModificationException! 即,产生fail-fast事件!

    结果说明 : 
    (01) FastFailTest 中通过 new ThreadOne().start() 和 new ThreadTwo().start() 同时启动两个线程去操作 list 。 
        ThreadOne线程 :向list中依次添加0,1,2,3,4,5。每添加一个数之后,就通过printAll()遍历整个list。 
        ThreadTwo线程 :向list中依次添加10,11,12,13,14,15。每添加一个数之后,就通过printAll()遍历整个list。 
    (02) 当某一个线程遍历list的过程中,list的内容被另外一个线程所改变了;就会抛出ConcurrentModificationException 异常,产生 fail-fast 事件。

    3 fail-fast解决办法

    fail-fast 机制,是一种错误检测机制。 它只能被用来检测错误,因为JDK并不保证fail-fast机制一定会发生。 若在多线程环境下使用 fail-fast 机制的集合,建议使用“java.util.concurrent 包下的类”去取代“ java.util 包下的类”。 
    所以,本例中只需要将 ArrayList 替换成 java.util.concurrent 包下对应的类即可。 
    即,将代码

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

    替换为

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

    则可以解决该办法。

    4 fail-fast原理

    产生 fail-fast 事件,是通过抛出 ConcurrentModificationException 异常来触发的。 
    那么, ArrayList是如何抛出ConcurrentModificationException异常的呢?

    我们知道, ConcurrentModificationException 是在操作 Iterator 时抛出的异常。我们先看看 Iterator 的源码。 ArrayList 的 Iterator 是在父类 AbstractList.java 中实现的。代码如下:

     1 package java.util;
     2 
     3 public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> {
     4 
     5     ...
     6 
     7     // AbstractList中唯一的属性
     8     // 用来记录List修改的次数:每修改一次(添加/删除等操作),将modCount+1
     9     protected transient int modCount = 0;
    10 
    11     // 返回List对应迭代器。实际上,是返回Itr对象。
    12     public Iterator<E> iterator() {
    13         return new Itr();
    14     }
    15 
    16     // Itr是Iterator(迭代器)的实现类
    17     private class Itr implements Iterator<E> {
    18         int cursor = 0;
    19 
    20         int lastRet = -1;
    21 
    22         // 修改数的记录值。
    23         // 每次新建Itr()对象时,都会保存新建该对象时对应的modCount;
    24         // 以后每次遍历List中的元素的时候,都会比较expectedModCount和modCount是否相等;
    25         // 若不相等,则抛出ConcurrentModificationException异常,产生fail-fast事件。
    26         int expectedModCount = modCount;
    27 
    28         public boolean hasNext() {
    29             return cursor != size();
    30         }
    31 
    32         public E next() {
    33             // 获取下一个元素之前,都会判断“新建Itr对象时保存的modCount”和“当前的modCount”是否相等;
    34             // 若不相等,则抛出ConcurrentModificationException异常,产生fail-fast事件。
    35             checkForComodification();
    36             try {
    37                 E next = get(cursor);
    38                 lastRet = cursor++;
    39                 return next;
    40             } catch (IndexOutOfBoundsException e) {
    41                 checkForComodification();
    42                 throw new NoSuchElementException();
    43             }
    44         }
    45 
    46         public void remove() {
    47             if (lastRet == -1)
    48                 throw new IllegalStateException();
    49             checkForComodification();
    50 
    51             try {
    52                 AbstractList.this.remove(lastRet);
    53                 if (lastRet < cursor)
    54                     cursor--;
    55                 lastRet = -1;
    56                 expectedModCount = modCount;
    57             } catch (IndexOutOfBoundsException e) {
    58                 throw new ConcurrentModificationException();
    59             }
    60         }
    61 
    62         final void checkForComodification() {
    63             if (modCount != expectedModCount)
    64                 throw new ConcurrentModificationException();
    65         }
    66     }
    67 
    68     ...
    69 }
    View Code

    从中,我们可以发现在调用 next() 和 remove() 时,都会执行checkForComodification() 。若 “ modCount 不等于 expectedModCount ”,则抛出ConcurrentModificationException 异常,产生 fail-fast 事件。

    要搞明白 fail-fast 机制,我们就要需要理解 什么时候“modCount 不等于 expectedModCount”! 
    从Itr类中,我们知道 expectedModCount 在创建Itr对象时,被赋值为 modCount 。通过Itr,我们知道: expectedModCount 不可能被修改为不等于 modCount 。所以,需要考证的就是 modCount 何时会被修改。

    接下来,我们查看 ArrayList 的源码,来 看看modCount是如何被修改的 。

      1 package java.util;
      2 
      3 public class ArrayList<E> extends AbstractList<E>
      4         implements List<E>, RandomAccess, Cloneable, java.io.Serializable
      5 {
      6 
      7     ...
      8 
      9     // list中容量变化时,对应的同步函数
     10     public void ensureCapacity(int minCapacity) {
     11         modCount++;
     12         int oldCapacity = elementData.length;
     13         if (minCapacity > oldCapacity) {
     14             Object oldData[] = elementData;
     15             int newCapacity = (oldCapacity * 3)/2 + 1;
     16             if (newCapacity < minCapacity)
     17                 newCapacity = minCapacity;
     18             // minCapacity is usually close to size, so this is a win:
     19             elementData = Arrays.copyOf(elementData, newCapacity);
     20         }
     21     }
     22 
     23 
     24     // 添加元素到队列最后
     25     public boolean add(E e) {
     26         // 修改modCount
     27         ensureCapacity(size + 1);  // Increments modCount!!
     28         elementData[size++] = e;
     29         return true;
     30     }
     31 
     32 
     33     // 添加元素到指定的位置
     34     public void add(int index, E element) {
     35         if (index > size || index < 0)
     36             throw new IndexOutOfBoundsException(
     37             "Index: "+index+", Size: "+size);
     38 
     39         // 修改modCount
     40         ensureCapacity(size+1);  // Increments modCount!!
     41         System.arraycopy(elementData, index, elementData, index + 1,
     42              size - index);
     43         elementData[index] = element;
     44         size++;
     45     }
     46 
     47     // 添加集合
     48     public boolean addAll(Collection<? extends E> c) {
     49         Object[] a = c.toArray();
     50         int numNew = a.length;
     51         // 修改modCount
     52         ensureCapacity(size + numNew);  // Increments modCount
     53         System.arraycopy(a, 0, elementData, size, numNew);
     54         size += numNew;
     55         return numNew != 0;
     56     }
     57    
     58 
     59     // 删除指定位置的元素 
     60     public E remove(int index) {
     61         RangeCheck(index);
     62 
     63         // 修改modCount
     64         modCount++;
     65         E oldValue = (E) elementData[index];
     66 
     67         int numMoved = size - index - 1;
     68         if (numMoved > 0)
     69             System.arraycopy(elementData, index+1, elementData, index, numMoved);
     70         elementData[--size] = null; // Let gc do its work
     71 
     72         return oldValue;
     73     }
     74 
     75 
     76     // 快速删除指定位置的元素 
     77     private void fastRemove(int index) {
     78 
     79         // 修改modCount
     80         modCount++;
     81         int numMoved = size - index - 1;
     82         if (numMoved > 0)
     83             System.arraycopy(elementData, index+1, elementData, index,
     84                              numMoved);
     85         elementData[--size] = null; // Let gc do its work
     86     }
     87 
     88     // 清空集合
     89     public void clear() {
     90         // 修改modCount
     91         modCount++;
     92 
     93         // Let gc do its work
     94         for (int i = 0; i < size; i++)
     95             elementData[i] = null;
     96 
     97         size = 0;
     98     }
     99 
    100     ...
    101 }
    View Code

    从中,我们发现:无论是 add() 、 remove() ,还是 clear() ,只要涉及到修改集合中的元素个数时,都会改变 modCount 的值。

    接下来,我们再系统的梳理一下fail-fast是怎么产生的。步骤如下: 
    (01) 新建了一个ArrayList,名称为arrayList。 
    (02) 向arrayList中添加内容。 
    (03) 新建一个“ 线程a ”,并在“线程a”中 通过Iterator反复的读取arrayList的值 。 
    (04) 新建一个“ 线程b ”,在“线程b”中 删除arrayList中的一个“节点A ”。 
    (05) 这时,就会产生有趣的事件了。 
           在某一时刻,“线程a”创建了arrayList的Iterator。此时“节点A”仍然存在于arrayList中, 创建arrayList时,expectedModCount = modCount (假设它们此时的值为N)。
           在“线程a”在遍历arrayList过程中的某一时刻,“线程b”执行了,并且“线程b”删除了arrayList中的“节点A”。“线程b”执行remove()进行删除操作时,在remove()中执行了“modCount++”,此时 modCount变成了N+1 ! 
    “线程a”接着遍历,当它执行到next()函数时,调用checkForComodification()比较“expectedModCount”和“modCount”的大小;而“expectedModCount=N”,“modCount=N+1”,这样,便抛出ConcurrentModificationException异常,产生fail-fast事件。

    至此, 我们就完全了解了fail-fast是如何产生的! 
    即,当多个线程对同一个集合进行操作的时候,某线程访问集合的过程中,该集合的内容被其他线程所改变(即其它线程通过add、remove、clear等方法,改变了modCount的值);这时,就会抛出ConcurrentModificationException异常,产生fail-fast事件。 

    5 解决fail-fast的原理

    上面,说明了“解决fail-fast机制的办法”,也知道了“fail-fast产生的根本原因”。接下来,我们再进一步谈谈 java.util.concurrent包中是如何解决fail-fast事件的 。 
    还是以和ArrayList对应的 CopyOnWriteArrayList 进行说明。我们先看看CopyOnWriteArrayList 的源码:

     1 package java.util.concurrent;
     2 import java.util.*;
     3 import java.util.concurrent.locks.*;
     4 import sun.misc.Unsafe;
     5 
     6 public class CopyOnWriteArrayList<E>
     7     implements List<E>, RandomAccess, Cloneable, java.io.Serializable {
     8 
     9     ...
    10 
    11     // 返回集合对应的迭代器
    12     public Iterator<E> iterator() {
    13         return new COWIterator<E>(getArray(), 0);
    14     }
    15 
    16     ...
    17    
    18     private static class COWIterator<E> implements ListIterator<E> {
    19         private final Object[] snapshot;
    20 
    21         private int cursor;
    22 
    23         private COWIterator(Object[] elements, int initialCursor) {
    24             cursor = initialCursor;
    25             // 新建COWIterator时,将集合中的元素保存到一个新的拷贝数组中。
    26             // 这样,当原始集合的数据改变,拷贝数据中的值也不会变化。
    27             snapshot = elements;
    28         }
    29 
    30         public boolean hasNext() {
    31             return cursor < snapshot.length;
    32         }
    33 
    34         public boolean hasPrevious() {
    35             return cursor > 0;
    36         }
    37 
    38         public E next() {
    39             if (! hasNext())
    40                 throw new NoSuchElementException();
    41             return (E) snapshot[cursor++];
    42         }
    43 
    44         public E previous() {
    45             if (! hasPrevious())
    46                 throw new NoSuchElementException();
    47             return (E) snapshot[--cursor];
    48         }
    49 
    50         public int nextIndex() {
    51             return cursor;
    52         }
    53 
    54         public int previousIndex() {
    55             return cursor-1;
    56         }
    57 
    58         public void remove() {
    59             throw new UnsupportedOperationException();
    60         }
    61 
    62         public void set(E e) {
    63             throw new UnsupportedOperationException();
    64         }
    65 
    66         public void add(E e) {
    67             throw new UnsupportedOperationException();
    68         }
    69     }
    70   
    71     ...
    72 
    73 }
    View Code

    从中,我们可以看出:

    (01) 和 ArrayList 继承于 AbstractList 不同, CopyOnWriteArrayList 没有继承于AbstractList ,它仅仅只是实现了 List 接口。 
    (02) ArrayList 的 iterator() 函数返回的 Iterator 是在 AbstractList 中实现的;而CopyOnWriteArrayList 是自己实现 Iterator 。 
    (03) ArrayList 的 Iterator 实现类中调用 next() 时,会“调用checkForComodification()比较‘expectedModCount’和‘modCount’的大小”;但是, CopyOnWriteArrayList 的Iterator实现类中,没有所谓的checkForComodification(),更不会抛出ConcurrentModificationException异常!


    原文: http://www.cnblogs.com/skywang12345/p/3308762.html

    展开全文
  • Java HashMap遍历过程中如果元素被修改会导致遍历失败,ConcurrentHashMap则不会有这...由此引出HashMap的fast-fail机制和ConcurrentHashMap的的fail-safe机制。 看如下实例。 首先看HashMap的fast-fail packa...

    声明:迁移自本人CSDN博客https://blog.csdn.net/u013365635

    Java HashMap遍历过程中如果元素被修改会导致遍历失败,ConcurrentHashMap则不会有这个问题。由此引出HashMap的fast-fail机制和ConcurrentHashMap的的fail-safe机制。

    看如下实例。
    首先看HashMap的fast-fail

    package com;
    
    import java.util.HashMap;
    import java.util.Map;
    
    public class TestHashMapFastFail
    {
        public static void main(String[] args)
        {
            System.out.println("test HashMap fast-fail");
            Map<Integer, String> testHashMap = new HashMap<Integer, String>();
            testHashMap.put(1000, "1000");
            testHashMap.put(2000, "2000");
            testHashMap.put(3000, "3000");
            testHashMap.put(4000, "4000");
            testHashMap.put(5000, "5000");
            System.out.println(testHashMap.size());
            for (Map.Entry<Integer, String> entry : testHashMap.entrySet())
            {
                int key = entry.getKey();
                System.out.println("key=" + key);
                if (key == 3000)
                {
                    testHashMap.remove(key);
                }
            }
            System.out.println(testHashMap.size());
            for (Map.Entry<Integer, String> entry : testHashMap.entrySet())
            {
                System.out.println(entry.getKey() + "-->" + entry.getValue());
            }
        }
    }
    

    运行结果

    test HashMap
    5
    key=2000
    key=4000
    key=1000
    key=3000
    Exception in thread "main" java.util.ConcurrentModificationException
    	at java.util.HashMap$HashIterator.nextNode(HashMap.java:1437)
    	at java.util.HashMap$EntryIterator.next(HashMap.java:1471)
    	at java.util.HashMap$EntryIterator.next(HashMap.java:1469)
    	at com.TestHashMapFastFail.main(TestHashMapFastFail.java:18)
    

    可以看到执行remove操作后,下一轮迭代立刻失效,并抛出异常,这就是所谓的fast-fail。

    再看ConcurrentHashMap的fail-safe

    package com;
    
    import java.util.Map;
    import java.util.concurrent.ConcurrentHashMap;
    
    public class TestConcurrentHashMapFailSafe
    {
        public static void main(String[] args)
        {
            System.out.println("test ConcurrentHashMap fast-fail");
            Map<Integer, String> testConcurrentHashMap = new ConcurrentHashMap<Integer, String>();
            testConcurrentHashMap.put(100, "100");
            testConcurrentHashMap.put(200, "200");
            testConcurrentHashMap.put(300, "300");
            testConcurrentHashMap.put(400, "400");
            testConcurrentHashMap.put(500, "500");
            System.out.println(testConcurrentHashMap.size());
            for (Map.Entry<Integer, String> entry : testConcurrentHashMap.entrySet())
            {
                int key = entry.getKey();
                System.out.println("key=" + key);
                if (key == 300)
                {
                    testConcurrentHashMap.remove(key);
                }
            }
            System.out.println(testConcurrentHashMap.size());
            for (Map.Entry<Integer, String> entry : testConcurrentHashMap.entrySet())
            {
                System.out.println(entry.getKey() + "-->" + entry.getValue());
            }
        }
    }
    

    运行结果

     test ConcurrentHashMap fast-fail
    5
    key=400
    key=100
    key=500
    key=200
    key=300
    3
    100-->100
    500-->500
    300-->300
    

    可以看出,尽管在迭代过程中执行了remove操作,但是ConcurrentHashMap对外的表现仍然正常,这就是所谓的fail-safe。原因在于ConcurrentHashMap返回的迭代器是弱一致性,ConcurrentHashMap底层数据结构改变时并且不会抛出ConcurrentModificationException异常。
    所以,这也是选择ConcurrentHashMap可以获得的一个额外好处,或者说是解决HashMap fast-fail的一种方法,还有一个方法就是使用迭代器的remove方法而不是使用集合的remove方法,示例如下。

    package com;
    
    import java.util.HashMap;
    import java.util.Iterator;
    import java.util.Map;
    
    public class TestHashMapFastFail2
    {
        public static void main(String[] args)
        {
            System.out.println("test solve HashMap fast-fail");
            Map<Integer, String> testHashMap = new HashMap<Integer, String>();
            testHashMap.put(1000, "1000");
            testHashMap.put(2000, "2000");
            testHashMap.put(3000, "3000");
            testHashMap.put(4000, "4000");
            testHashMap.put(5000, "5000");
            System.out.println(testHashMap.size());
            Iterator iterator = testHashMap.entrySet().iterator();
            while (iterator.hasNext())
            {
                int key = (int)((Map.Entry)iterator.next()).getKey();
                System.out.println("key=" + key);
                if (key == 2000 || key == 4000)
                {
                    iterator.remove();
                }
            }
            System.out.println(testHashMap.size());
            for (Map.Entry<Integer, String> entry : testHashMap.entrySet())
            {
                System.out.println(entry.getKey() + "-->" + entry.getValue());
            }
        }
    }
    

    运行结果

    test solve HashMap fast-fail
    5
    key=2000
    key=4000
    key=1000
    key=3000
    key=5000
    3
    1000-->1000
    3000-->3000
    5000-->5000
    

    集合的 fast-fail 问题是初学者很容易犯的错误。
    说说fast-fail机制和fail-safe机制设计的原因。有人可能会问,既然fast-fail有这么多弊端,为什么还要设计呢,以HashMap为例,因为HashMap本身就是设计成线程不安全的,不支持多个线程同时安全修改,但这也意味着HashMap有较快的速度。fail-safe机制设计的初衷就是保证多线程并发安全地修改集合或Map类。当然,本文的用例都是单线程中的修改操作,主要是为了引出这2个概念。至于内部实现机制,看源码吧。

     

    转载于:https://www.cnblogs.com/xsl-thumb-rfcs/p/9941596.html

    展开全文
  • fast-fail是什么?

    2021-07-09 09:28:38
    fast-fail1 fast-fail2 原因:3 单线程例子4 多线程例子 1 fast-fail 当多个线程对集合进行迭代器遍历时,改变了集合的结构时(比如 移除了元素 添加了元素 集合的长度发生改变)就会fast-fail 2 原因: 迭代器进行...

    1 fast-fail

    当多个线程对集合进行迭代器遍历时,改变了集合的结构时(比如 移除了元素 添加了元素 集合的长度发生改变)就会fast-fail

    2 原因:

    迭代器进行迭代操作的时候,会有一个modCount的值,如果有人修改集合,modCount会发生改变,就会抛出java.util.ConcurrentModificationException异常
    

    3 单线程例子

    import java.io.*;
    import java.util.*;
    import java.util.concurrent.ConcurrentHashMap;
    
    class Solution {
    
        public static void main(String[] args) throws IOException {
            List<String> list = new ArrayList<>();
            for (int i = 0; i < 10; i++) {
                list.add(i + "");
            }
            Iterator<String> iterator = list.iterator();
            int i = 0;
            while (iterator.hasNext()) {
                if (i == 3) {
                    list.remove(3);
                }
                System.out.println(iterator.next());
                i++;
            }
        }
    }
    
    

    结果

    0
    1
    2
    Exception in thread "main" java.util.ConcurrentModificationException
    	at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:909)
    	at java.util.ArrayList$Itr.next(ArrayList.java:859)
    	at Solution.main(Solution.java:18)
    

    4 多线程例子

    import java.io.*;
    import java.util.*;
    import java.util.concurrent.ConcurrentHashMap;
    
    class Solution {
        public static List<String> list=new ArrayList<>();
        public static void main(String[] args) throws IOException {
           new ThreadOne().start();
           new ThreadTwo().start();
        }
    
        private static void printAll(){
            Iterator it=list.iterator();
            while(it.hasNext()){
                System.out.println((String)it.next());
            }
            System.out.println("----------------------分割线-------------------------");
        }
    
        public static class ThreadOne extends Thread{
            public void run(){
                for(int i=1;i<10;i++){
                    list.add("我是线程一"+i);
                    printAll();
                }
            }
        }
    
        public static class ThreadTwo extends Thread{
            public void run(){
                for(int i=1;i<30;i++){
                    list.add("我是线程二"+i);
                    printAll();
                }
            }
        }
    }
    
    

    结果

    我是线程一1
    ----------------------分割线-------------------------
    我是线程一1
    我是线程一2
    ----------------------分割线-------------------------
    我是线程一1
    我是线程一2
    我是线程一3
    ----------------------分割线-------------------------
    我是线程一1
    我是线程一2
    我是线程一3
    我是线程一4
    ----------------------分割线-------------------------
    
    ..........省略..........
    
    我是线程二23
    我是线程二24
    我是线程二25
    我是线程二26
    我是线程二27
    我是线程二28
    我是线程二29
    ----------------------分割线-------------------------
    Exception in thread "Thread-0" java.util.ConcurrentModificationException
    	at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:909)
    	at java.util.ArrayList$Itr.next(ArrayList.java:859)
    	at Solution.printAll(Solution.java:15)
    	at Solution.access$000(Solution.java:5)
    	at Solution$ThreadOne.run(Solution.java:24)
    
    Process finished with exit code 0
    
    展开全文
  • fail-fast机制fail-fast:它是Java集合(Collection)的一种错误机制。当多个线程对同一个集合进行修改结构操作,使用集合的迭代器iterator,会首先检测是否有对集合的并发修改,进而产生...
  • collection中的fast-fail机制 摘自[java Generics and Collections] The policy of the iterators for the Java 2 collections is to fail fast, as described in Section 11.1: every time they access the ...
  • 已经有很多帖子分析了Fast-fail机制,就不累述了。 往往我们喜欢把知识点提炼成最精简的话语放到大脑里,就是 Fast-fail机制是为了防止迭代器进行集合迭代过程中对集合元素进行增加或删除(包括单线程和多线程),...
  • fast-fail机制

    2016-10-17 11:12:12
    “快速失败”也就是fail-fast,它是Java集合的一种错误检测机制。在集合中经常遇到 java.util.ConcurrentModificationException异常,而产生这个原因就是fail-fast,主要发生在集合的迭代输出时,而在此时可能这个...
  • fail-fast机制简介 什么是fail-fast fail-fast 机制是java集合(Collection)中的一种错误机制。它只能被用来检测错误,因为JDK并不保证fail-fast机制一定会发生。当多个线程对同一个集合的内容进行操作时,就可能会...
  • 1、fail-fast简介 fail-fast机制是java集合(Collection)中的一个错误机制。当多个线程对同一个集合的内容进行操作时,就可能会产生fail-fast事件。 例如:当某一个线程A通过iterator去遍历某集合的过程中,若该...
  • fail-fast机制,是一种错误检测机制。它只能被用来检测错误,因为JDK并不保证fail-fast机制一定会发生。若在多线程环境下使用fail-fast机制的集合,建议使用“java.util.concurrent包下的类”去取代“java.util包下...
  • fast-fail机制解析

    2017-04-12 15:14:41
    通过上面的示例和讲解,我初步知道fail-fast产生的原因就在于程序在对 collection 进行迭代时,某个线程对该 collection 在结构上对其做了修改,这时迭代器就会抛出 ConcurrentModificationException 异常信息,从而...
  • Java集合的fast-fail机制

    2019-07-14 14:48:47
    fail-fast 机制是java集合(Collection)中的一种错误机制。在我们常用的ArrayList和LinkedList中,采用了该机制 当多个线程对同一个集合的内容进行操作时,就可能会产生fail-fast事件。 例如: 当某一个线程A通过...
  • 前言: 学号java基础,我们才能在开发中游刃有余的解决问题,才会减少BUG的出现...注意:迭代器的fail-fast机制并不能被保证一定会发生,一般来说,在存在不同步的并发修改时不可能做出任何有力保证,但是fail-fas...
  • 参考自:http://www.cnblogs.com/skywang12345/p/3308762.htmlfail-fast 定义fail-fast(快速失败)机制:是Java集合中的一种检错机制。当某个线程用iterator对list进行遍历时,其他线程同时并发的对list进行插入...
  • 1、fail-fast事件出现的情景 1 import java.util.*; 2 import java.util.concurrent.*; 3 4 /* 5 * 6 * 7 * fail-fast事件产生的条件:当多个线程对Collection进行操作时,若其中某一个线程通过...
  • Iterator、fast-fail 机制

    2018-05-17 14:29:32
     使用该机制的主要目的是为了实现ArrayList中的快速失败机制(fail-fast),在Java集合中较大一部分集合是存在快速失败机制的。  快速失败机制产生的条件:当多个线程对Collection进行操作时,若其中某一个线程通过...
  • fail-fast 机制是java集合(Collection)中的一种错误机制。当多个线程对同一个集合的内容进行操作时,就可能会产生fail-fast事件。例如:当某一个线程A通过iterator去遍历某集合的过程中,若该集合的内容被其他线程...
  • 快速失败(fast-fail)

    2018-09-30 11:27:20
  • 快速报错(fail-fast):如果在生成迭代器后,集合被修改(除了迭代器remove方法),迭代器将抛出异常ConcurrentModificationException。 因此,在并发修改的情况下,迭代器会迅速失败,而不会去等待。 注意,也...
  • 1、 fail-fast简介  fail-fast 机制是java集合(Collection)中的一种错误机制。  如果运行代码,抛出异常java.util.ConcurrentModificationException,即产生fail-fast事件!  fail-fast机制,是一种错误检测...
  • 其实,这是一种理念,fail-fast就是在做系统设计的时候先考虑异常情况,一旦发生异常,直接停止并上报。 所以说fast-fail是为了报告系统出现异常,而不具有去解决这个异常的能力。 那么问题就来了,为什么...
  • java数据结构与算法之改良顺序表与双链表类似ArrayList和LinkedList(带Iterator迭代器与fast-fail机制) java数据结构与算法之栈(Stack)设计与实现 java数据结构与算法之队列(Queue)设计与实现 java...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 47,462
精华内容 18,984
关键字:

fast-fail