Java Specialists' Java Training Europehome of the java specialists' newsletter

The Java Specialists' Newsletter
Issue 1762009-09-22 Category: Tips and Tricks Java version: 5+

GitHub Subscribe Free RSS Feed

The Law of the Xerox Copier

by 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: We have revised our "Advanced Topics" course, covering Reflection, Java NIO, Data Structures, Memory Management and several other useful topics for Java experts to master. 2 days of extreme fun and learning. Extreme Java - Advanced Topics.

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

Tips and Tricks Articles Related Java Course

Extreme Java - Concurrency and Performance for Java 8
Extreme Java - Advanced Topics for Java 8
Design Patterns
In-House Courses

© 2010-2016 Heinz Kabutz - All Rights Reserved Sitemap
Oracle and Java are registered trademarks of Oracle and/or its affiliates. Other names may be trademarks of their respective owners. JavaSpecialists.eu is not connected to Oracle, Inc. and is not sponsored by Oracle, Inc.