What is the logic of a fail safe iterator?

寵の児 提交于 2019-12-21 04:18:24

问题


If fail-safe iterator creates a separate copy and works on that, how come it is aware of any changes made to the original?

public class concurrentHashMap {
    public static void main(String[] args) throws InterruptedException {
        MapCheck obj1 = new MapCheck();
        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                obj1.put();
            }
        });

        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                obj1.iterte();
            }
        });

        t1.start();
        t2.start();
        t1.join();
        t2.join();
    }
}

class MapCheck {
    Map<Integer,String> map = new ConcurrentHashMap<>();
    {
        map.put(1, "pujan");
        map.put(2, "manish");
        map.put(3, "swati");
    }

    void iterte() throws InterruptedException {
        for (int key : map.keySet()) {
            Thread.sleep(2000);
            System.out.println(map.get(key));
        }
    }

    void put() throws InterruptedException{
        Thread.sleep(2000);
        map.put(1, "pujan1");
        map.put(2, "manish1");
        map.put(3, "swati1");
    }
}

The output is:

pujan1
manish1
swati1

回答1:


There is no such thing as a "fail-safe" iterator in Java. At least, the Java SE specifications do not define such a term. I therefore recommend that you avoid using the term "fail-safe" to describe Java iterators.

I'm well aware that various articles on the Internet and elsewhere on Stack Overflow use the term "fail-safe", but their usage is not definitive, and it's likely to be incorrect or at the very least misleading. I believe you've been misled by such documentation.

It sounds like you read somewhere that a "fail-safe" iterator works on a separate copy. In your example, you use a ConcurrentHashMap, which indeed has iterators that aren't fail-fast. However, CHM's iterators don't operate on a copy. Instead, they have semantics that are described by the official specification as weakly consistent. The definition is somewhat abstruse, but essentially, any element reported by such an iterator is guaranteed to have existed in the collection at some point in time. These kind of iterators might or might not reflect changes to the collection that were made after the iteration started. That's why the thread that's running the iterator sees changes made by the other thread. (It's also possible for some or none of the changes to be visible, since these threads have a data race.)

An example of another collection whose iterators are not fail-fast is CopyOnWriteArrayList. This collection's iterators operate on a snapshot, so any subsequent changes to the collection are never visible via an iterator.

For completeness, here is the definition of a fail-fast iterator from the ArrayList specification. Most of the other (non-concurrent) collections in Java have a fail-fast iteration policy that's defined similarly.



来源:https://stackoverflow.com/questions/38341059/what-is-the-logic-of-a-fail-safe-iterator

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!