Home of The JavaSpecialists' Newsletter

176The Law of the Xerox Copier

Posted: 2009-09-22Category: Tips and TricksJava Version: 1.5+Dr. Heinz M. Kabutz
 

Abstract: 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 ... :-)

NEW: Refactoring to Java 8 Streams and Lambdas Workshop Are you currently using Java 6 or 7 and would like to see how Java 8 can improve your code base? Are you tired of courses that teach you a whole bunch of techniques that you cannot apply in your world? Check out our one day intensive Refactoring to Java 8 Streams and Lambdas Workshop.

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.

  1. The Law of the Sabotaged Doorbell
  2. The Law of the Distracted Spearfisherman
  3. The Law of the Overstocked Haberdashery
  4. The Law of the Blind Spot
  5. The Law of the Leaked Memo
  6. The Law of the Corrupt Politician
  7. The Law of the Micromanager
  8. The Law of Cretan Driving
  9. The Law of Sudden Riches
  10. The Law of the Uneaten Lutefisk
  11. 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

 

Related Articles

Browse the Newsletter Archive

About the Author

demo

Java Champion, author of the Javaspecialists Newsletter, conference speaking regular... About Heinz

Java Training

We deliver relevant courses, by top Java developers to produce more resourceful and efficient programmers within their organisations.

Java Consulting

Nobody ever wants to call a Java performance consultant, but with first-hand experience repairing and improving commercial Java applications - JavaSpecialists are a good place to start...

Threading Emergency?

If your system is down, we will review it for 15 minutes and give you our findings for just 1 € without any obligation.