4

I get this definition : As name suggest fail-fast Iterators fail as soon as they realized that structure of Collection has been changed since iteration has begun.

what it mean by since iteration has begun? is that mean after Iterator it=set.iterator() this line of code?

public static void customize(BufferedReader br) throws IOException{  
    Set<String> set=new HashSet<String>(); // Actual type parameter added  
    **Iterator it=set.iterator();**
joy
  • 721
  • 2
  • 11
  • 18
  • Please name the language you're working with and use some meaningful tags. – cxxl Nov 25 '12 at 09:55
  • correct, talking about when iterator started. However, as per jsr, it's not guaranteed failed-fast, so be careful of using it. – Jackie Jun 03 '13 at 14:04

5 Answers5

9

First of all, they are fail-fast, not fail-safe.

The contract is that structural modifications (i.e. insertions/deletions) of certain types of collections invalidate existing iterators into the collection. Fail-fast iterators attempt to detect that they are not supposed to be valid and throw a ConcurrentModificationException. This is done as a service to you, the programmer, to help discover this type of bugs quicker.

In your example:

Iterator it = set.iterator();
it.next();
set.add("unique-entry"); // invalidates the iterator
it.next();

If you're lucky, the second it.next() will detect the invalid usage and throw an exception. Note that this is done on a best-effort basis and is not guaranteed.

NPE
  • 486,780
  • 108
  • 951
  • 1,012
  • I have try the code. no exception is throws. Is this a fail-safe example instead? – joy Nov 25 '12 at 11:01
  • 1
    Again, it's **best-effort**. The iterator may or may not detect the invalid usage. – NPE Nov 25 '12 at 11:02
  • thanks. this clear up my mind that fail-fast not necessary throws exception bacause not detected. – joy Nov 25 '12 at 11:15
2

The iterator being fail-fast means the following piece of code is expected to fail:

Set<String> set = new HashSet<String>();
Iterator<String> it = set.iterator();
set.add("");
it.next();   // the set has changed now, and the iterator will throw an exception

because the following series of events occur: The iterator is created, then its underlying collection changes, then the iterator is accessed.

John Dvorak
  • 26,799
  • 13
  • 69
  • 83
  • @Mehrdad the fail-fast behavior of Java Foundation Classes only fails if a multiple of 2^32 modifications occurs between the uses. – John Dvorak Nov 25 '12 at 10:02
  • 1
    I think that's just how it happens to be implemented currently, but it's not guaranteed to be that way by the specs. So it could very well change in the future. It's important to only use the guarantees provided by the specs instead of making assumptions about the implementation... and AFAIK they explicitly say it's on a best-effort basis, not a guaranteed basis. – user541686 Nov 25 '12 at 10:18
  • @Mehrdad still I don't think any reasonable implementation (unless the check is removed completely) will fail to detect _this_ case. – John Dvorak Nov 25 '12 at 10:21
  • 1
    Yeah, I don't either, but then again, these 4 lines of code probably aren't going into production either, so their value in themselves is pretty low. What *is* more likely to survive from them is the *reasoning* drawn from this example, which is why I was worried about giving the wrong impression of the meaning of fail-fast to the OP -- it's important enough to point out that it's on a best-effort basis, but if you don't go that route it's even more critical to avoid implying there would be a guarantee. – user541686 Nov 25 '12 at 10:35
2

is that mean after Iterator it=set.iterator() this line of code?

Yes. If you look at the code for HashSet.iterator() you'll see it's just this:

return map.keySet().iterator();

... which delegate's to HashMap.KeySet.iterator(). There are a few more links in the chain, but eventually you get to HashMap.HashIterator, which contains this in the constructor:

private abstract class HashIterator<E> implements Iterator<E> {
    int expectedModCount;   // For fast-fail

    ...

    HashIterator() {
        expectedModCount = modCount;
        ...
    }
}

... where modCount is a field in the enclosing instance of HashMap which keeps track of the number of modifications.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
0

yes, don't change the collection after using .iterator() if you are planning to iterate over it , you can use the .remove() if you want to remove the latest element though

Jimmar
  • 4,194
  • 2
  • 28
  • 43
0

Before Fail Fast Iterator is starting to work it’s getting count of collection and after any iteration it is checking if count is changed or not, and in case of changed count JVM will throw ConcurrentModificationException. Fail fast iterators are any iterator of collection which is inside java.util package(e.g. ArrayList, LinkedList etc) and Fail Safe iterators are iterators which are inside of java.concurrent package(e.g. CopyOnWriteArrayList, CopyOnWriteSet etc.). Fail Fast iterators will throw exception in case of concurrent modification but Fail Safe iterator is basically working with copy of collection which is not throwing exception in case of concurrent modification.

Arman Tumanyan
  • 386
  • 3
  • 14