The difference between fail-fast and fail-safe in java

First of all, it is necessary to understand the concept of synchronous modification, which means that one or more threads are traversing a collection, and another thread modifies the data structure of the Collection (add, delete or modify);

1.fail-fast mechanism

The fail-fast mechanism throws Concurrent Modification Exception directly when the collection element is modified when the collection is traversed. There are two situations;

1> In a single-threaded environment

After the collection is created, the structure is modified in the process of traversing it. Note that the remove() method will make expectModcount and modcount equal, so this exception will not be thrown.

2> In a multi-threaded environment

While one thread is traversing an element, another thread makes changes to the element

The principle of fail-fast mechanism verification is to internally maintain an identifier "mode". When the collection data structure is modified, the mode is modified; the next and hasNext methods of each traversal will check whether the "mode" has been modified. Concurrent Modification Exception is thrown

For example, the source code of the ArrayList iteration part

private class Itr implements Iterator<E> {
        int cursor;       // index of next element to return
        int lastRet = -1; // index of last element returned; -1 if no such
        int expectedModCount = modCount;

        public boolean hasNext() {
            return cursor != size;
        }

        @SuppressWarnings("unchecked")
        public E next() {
            checkForComodification();
            int i = cursor;
            if (i >= size)
                throw new NoSuchElementException();
            Object[] elementData = ArrayList.this.elementData;
            if (i >= elementData.length)
                throw new ConcurrentModificationException();
            cursor = i + 1;
            return (E) elementData[lastRet = i];
        }

        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();
            }
        }

2.fail-safe mechanism

The fail-safe mechanism copies a new object every time the collection is modified, so no ConcurrentModificationException is thrown,

There are two problems with the fail-safe mechanism

(1) The collection needs to be copied, a large number of invalid objects are generated, and the overhead is high

(2) There is no guarantee that the data read is the data in the current original data structure.

3. Examples of fail-fast and fail-safe mechanisms

package com.example.springbootDemo.service;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

public class FailFastExample {
    public static void main(String[] args) {
        Map<String,String> premiumPhone = new HashMap<String,String>();
        premiumPhone.put("Apple", "iPhone");
        premiumPhone.put("HTC", "HTC one");
        premiumPhone.put("Samsung","S5");

        Iterator iterator = premiumPhone.keySet().iterator();

        while (iterator.hasNext())
        {
            System.out.println(premiumPhone.get(iterator.next()));
            premiumPhone.put("Sony", "Xperia Z");
        }
    }
}
package com.example.springbootDemo.service;

import java.util.Iterator;
import java.util.concurrent.ConcurrentHashMap;

public class FailSafeExample {
    public static void main(String[] args) {
        ConcurrentHashMap<String,String> premiumPhone =
                new ConcurrentHashMap<String,String>();
        premiumPhone.put("Apple", "iPhone");
        premiumPhone.put("HTC", "HTC one");
        premiumPhone.put("Samsung","S5");

        Iterator iterator = premiumPhone.keySet().iterator();

        while (iterator.hasNext())
        {
            System.out.println(premiumPhone.get(iterator.next()));
            premiumPhone.put("Sony", "Xperia Z");
        }
        System.out.printf("premiumPhone:"+premiumPhone.toString());
    }
}

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325079464&siteId=291194637