Cameron McKenzie: Hey, I'm Cameron McKenzie, the
editor in chief over at TheServerSide.com. And I
want to talk to you about iterators. Specifically,
I want to compare and contrast fail safe versus
fail fast iterators in Java. Starting off, I've
got the structure of a Java class, I've got the
main method. And I've also got the failsafe
iterator method. And I've also got the fail fast
iterator method, which I will use to compare and
contrast the two types of iterators. I'm going to
start off in the fail fast iterator method and
show you an example of failing fast and
specifically the exception that gets thrown when
you try and edit a collection inside of an
iteration over the loop. So to start off, I'm
going to create a new ArrayList that holds string
objects, we'll call it servers, it'll be an
ArrayList. That takes strings. And after that
ArrayList is created, you got to spell it
properly. I don't know just add, add my favorite
server Tomcat, although jetty actually comes with
a close second there. So now I've got an array
list with one item in it. It's not a lot. But
let's say I want to iterate over that. Well, I
could create an iterator object. So I can pull all
the objects in that collection out as an iterator.
iterator is a good name for it. So I say Hey, get
that ArrayList called servers. And let's get the
iterator out of it. So that gives me the iterator.
Now, all I have to do is write a while loop.
iterator dot has Next is the method that you use
to move on to the next element in the collection.
If I want to get the name of the current server
being iterated over, I could just say string
server equals iterator dot next, since there's
only one the first time through the loop, that's
going to give me the name Tomcat, and then just
print out the name of the server. Now, when I run
this, well, everything works great. It's not that
impressive, but Tomcat prints out. But watch this.
If during the while loop, I say servers dot add
and add jetty in, well, all of a sudden, I am now
going to be manipulating this ArrayList I'm going
to be changing the number of elements in the
array, I'm going to be manipulating the data
structure while the iterator is working. And if I
do that, all hell is gonna break loose, the
program's gonna say, look, you cannot change a
collection class while you are working on an
iterator while you were iterating through it. So
watch if I run this application while I get the
Java util concurrent modification exception,
because I'm iterating through a collection, and
I'm modifying it at the same time or some other
thread is modifying it. And so that's how you end
up with the concurrent modification exception you
are iterating through a collection. But while
you're iterating, somebody actually goes in and
changes that collection. So that is the nefarious
concurrent modification exception. Now, there is a
way around that. And one way around that is to use
collection class that does not fail fast, right.
As soon as the JVM detects the fact that you are
changing the underlying data, it throws that
exception, a fail fast iterator won't do that, at
least it appears that it won't do that. So here,
let me get a list of my favorite servers. And I'm
going to use a special collection class from
things Java dot util dot concurrent package. It's
called the copy on write ArrayList. So it's an
ArrayList of type strings, just like this is an
ArrayList of type strings. It's just a special
type. And you can see here in the constructor I've
passed in this data here. So there's the array of
strings with all of my favorite servers on them.
There is that array of strings being passed into
the copy on write ArrayList, which uses a failsafe
iterator. And I'm not going to loop through that.
So iterator string iterator
equals data list. That's the name of list dot
iterator. We've seen this code before. And then I
can say while iterator dot has next, and let's
loop through here. So what do I want to do here?
Well, maybe I will get the name of the server and
print it out, kind of like I did on the previous
One you know what I'm going to comment out the
fail fast iterator and then run this application.
And that way I can have the application run and
the exception not get thrown. So you can see right
here, we're just looping through all of the
elements in my list, Tomcat undertow, Kubernetes,
WebSphere, and j boss. And it all gets printed
out. But watch this. I'm going to actually edit
the list during the iterator. So why did I say
something like this? If server dot equals Tomcat?
Well, what I want to do well, if it equals Tomcat
kind of take that data list. I add the word jetty
to it, because I really like the eclipse jetty
application server. Okay, so now I've added the
word jetty to this ArrayList. And I added it as
soon as we hit Tomcat. So that'll happen right at
the start. So we'll get our copy on write
ArrayList will have 12345 things in it, I will add
a sixth. And will this cause a problem? Will it
cause an exception? Well, let's run this as a Java
application. Boom, it does not cause a problem.
However, notice that jetty never gets printed out.
So even though we've added debt jetty to this data
list here, it actually doesn't get printed out,
even though we add it, you know, immediately after
we've loop on Tomcat. Now, the reason for that is
that this iterator doesn't actually point to that
ArrayList. The iterator actually is a copy of this
ArrayList. So when you use a failsafe iterator,
the iterator doesn't actually loop through the
underlying collection creates a copy of that
collection, and it loops through the copy. So if
you manipulate the underlying collection, well,
you know, it doesn't affect your iterator, it
doesn't affect your code, you don't throw an
exception, because it's actually not the
collection that you're working within that
iterator that's getting modified, right, you have
a clone, you have a copy of it. And so that's how
you avoid the exception. But as you can see,
there's drawbacks here. So all of a sudden, the
results may actually be out of sync with the
underlying data. So you gotta pick your poison, do
you want to make sure that nobody can manipulate
the data underneath you while you loop through it?
If so, you have it throw an exception. If you
know, maybe being out of sync a little bit is
bearable. You can use a fail safe iterator and
deal with the fact that from time to time, maybe
your results won't be exactly in sync in the
underlying data. It's also worth noting that
making that copy while making that copy is going
to cause extra resources to be consumed. So you
need extra memory for that. And also, you know, if
you're allocating a lot of objects and then
destroying them, after you're done with them,
you're probably going to have a lot of Java
garbage collection as well in Java garbage
collection can occupy CPU cycles. And it can cause
stop the world events. So it's something we want
to avoid as well. So again, you know, pick your
poison. Which one do you want, which one is best?
a failsafe iterator or fail fast iterator. Really.
That's something you got to decide on your
project.