|
The Java Specialists' Newsletter
Issue 176 2009-09-22
Category:
Tips and Tricks
Java version: 5+ The Law of the Xerox Copierby Dr. Heinz M. KabutzAbstract:
Concurrency is easier when we work with immutable objects.
In this newsletter, we define another concurrency law, The
Law of the Xerox Copier, which explains how we can work
with immutable objects by returning copies from methods
that would ordinarily modify the state.
Welcome to the 176th issue of The Java(tm) Specialists'
Newsletter, sent to you from Oslo in Norway. The
JavaZone
conference is wonderful, with at least one interesting
topic per session. There are actually two other talks
I'd like to attend when I am speaking tomorrow ...
Thanks for the feedback after my last newsletter, where I
showed how to construct objects
without calling any constructor. When I wrote
the article, I felt it unnecessary to explicitely state that
making a linkage to sun.* classes would be a problem for
portability of your code, since that is rather obvious. So
there, I've said it ... :-)
Upcoming Java Specialist Master Courses:
- please click here to sign up.
As from May 2010, we are also offering this course on the island of Crete. We
only accept 6 students per class in Crete, due to the size of our conference
room. Please book early to avoid disappointment!
San Jose CA, Mar 16-19 2010, $3500 Ottawa, Canada, Mar 22-25 2010, $3500 Oslo, Norway, Apr 13-16 2010, Kr 24500 Montreal, Canada, Apr 20-23 2010, $3500 Toronto, Canada, May 17-20 2010, $3500 Chania, Crete, May 25-28, Jun 29-Jul 2 or Aug 24-27 2010, €2500
In-house courses if these dates or locations do not suit you - click here for more information. The Law of the Xerox Copier
In previous newsletters, we looked at a series of laws to
make sense of Java concurrency. Just to remind you, here they
are again. In this newsletter, I would like to add a new one
to our list, the Law of the Xerox Copier.
- The Law of the Sabotaged Doorbell
- The Law of the Distracted Spearfisherman
- The Law of the Overstocked Haberdashery
- The Law of the Blind Spot
- The Law of the Leaked Memo
- The Law of the Corrupt Politician
- The Law of the Micromanager
- The Law of Cretan Driving
- The Law of Sudden Riches
- The Law of the Uneaten Lutefisk
- The Law of the Xerox Copier
The Law of the Xerox Copier
Protect yourself by making copies of objects.
At the end of 2008, we found a beautiful house in Crete that
we wanted to purchase. We only had one tiny little problem.
Houses in general are kind of expensive and I didn't have all
that much in my wallet. So we started the long process of
begging banks for a loan, which involves giving them reams of
paperwork.
You would imagine that it is safe to give a bank your
documents, expecting them to look after them until they
returned them. Well, the night before the bank was supposed
to give back our paperwork, loan denied of course, they were
attacked by a mob of angry protesters who completely trashed
it, together with our documents. How often does an event
like that happen? Fortunately, we had protected our original
objects by only giving copies to the loan consultant.
Coming back to concurrency, it is usually a good idea to make
your objects as immutable as possible. Instead of then
changing the object, we would return a new copy containing
the changes.
Immutable objects are always thread safe. We cannot have
stale values, race conditions or early writes. According to
Brian Goetz, an
immutable class is defined as the following:
State cannot be modified after construction
All the fields are final
'this' reference does not escape during construction
An example of an immutable class is String. Whenever we
"modify" it, such as with the + operator or the toUpperCase()
method. This causes additional work for the garbage
collector, but concurrency is much easier.
In Scala , we even have
immutable lists. How could that work in Java? Here is an
example:
import java.util.Iterator;
public class ImmutableArrayList<E> implements Iterable<E> {
private final Object[] elements;
public ImmutableArrayList() {
this.elements = new Object[0];
}
private ImmutableArrayList(Object[] elements) {
this.elements = elements;
}
public int size() {
return elements.length;
}
public ImmutableArrayList<E> add(E e) {
Object[] new_elements = new Object[elements.length + 1];
System.arraycopy(elements, 0,
new_elements, 0, elements.length);
new_elements[new_elements.length - 1] = e;
return new ImmutableArrayList<E>(new_elements);
}
public Iterator<E> iterator() {
return new Iterator<E>() {
private int pos = 0;
public boolean hasNext() {
return pos < elements.length;
}
public E next() {
return (E) elements[pos++];
}
public void remove() {
throw new UnsupportedOperationException();
}
};
}
}
Making ArrayList immutable is probably going overboard, a
better approach might be to just use the
CopyOnWriteArrayList, which also gives us great concurrent
performance.
We can use this ImmutableArrayList in a more functional
coding approach:
public class ImmutableArrayListTest {
public static void main(String[] args) {
ImmutableArrayList<String> ial =
new ImmutableArrayList<String>();
ial = ial.add("Heinz").add("Max").add("Kabutz");
for (Object obj : ial) {
System.out.println(obj);
}
}
}
Making copies of objects has helped me out of a fix many
times in the past, where rather complicated concurrency bugs
would have been tricky to resolve otherwise.
Kind regards from Oslo
Heinz
Concurrency Articles
Related Java Course
|