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

The Java Specialists' Newsletter
Issue 1512007-10-04 Category: Concurrency Java version: 5+

GitHub Subscribe Free RSS Feed

The Law of the Leaked Memo

by Dr. Heinz M. Kabutz
Abstract:
In this fifth law of concurrency, we look at a deadly law where a field value is written early.

Welcome to the 151st issue of The Java(tm) Specialists' Newsletter, sent to you from the Island of Crete somewhere in the Mediterranean. I am sitting inside writing this newsletter, so no beach stories today. Outside is a chilly 24 Celsius / 75 Fahrenheit.

This coming Saturday (6th October 2007) I am presenting a talk on the Secrets of Concurrency at the Java Hellenic User Group in Athens. Next week on Thursday (11th October 2007), I am presenting the same talk at the JFall 07 conference in Bussum, Netherlands. Come say "hi" if you are at either of these events :-)

NEW: Please see our new "Extreme Java" course, combining concurrency, a little bit of performance and Java 8. Extreme Java - Concurrency & Performance for Java 8.

The Law of the Leaked Memo

We are looking at a series of laws to make sense of Java concurrency. Just to remind you, here they are again. In this newsletter, we will look at the Law of the Leaked Memo.

  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 Leaked Memo

This may never happen, but when it does, check your synchronization.

Imagine for a moment that you are the director of a listed company. You are going to announce tomorrow that 50% of the staff is being retrenched. You have secretly typed the memo on your own laptop and personally made 500 photocopies. The reason why this information must not be leaked is because it will undoubtedly affect the share price, allowing someone with insider knowledge to make a quick buck and landing you in jail. However, after you make the 500 copies, you forget to remove the original memo from the photocopy machine. The secretary thread picks up the memo accidentally and soon there is widespread panic in the company.

It can happen in Java that without proper synchronization, a field value might be leaked before it should. The Java Memory Model gives the implementors the abiliy to reorder statements. To the Java thread, everything will appear to be in the same order, but other threads might see your early writes.

Let's look at an example:

  public class EarlyWrites {
    private int x;
    private int y;

    public void f() {
      int a = x;
      y = 3;
    }

    public void g() {
      int b = y;
      x = 4;
    }
  }
  

If two threads call f() and g(), what are the possible values for a and b at the end of the methods? The obvious answers are a=4,b=0 and a=0,b=3. Another fairly obvious answer is a=0,b=0 if the scheduler swaps between the threads after the first line of either method was executed.

However, there is a fourth possibility. Both threads might reorder the statements, resulting in:

    public void f() {
      y = 3;
      int a = x;
    }

    public void g() {
      x = 4;
      int b = y;
    }
  

This can result in a=4,b=3.

This reordering can happen at most places of the program. There are some restrictions though. For example, if you have a synchronized block, the hotspot compiler can reorder statements inside the block and it can move statements that lie outside the synchronized block into the block. However, it may not move code that is inside a synchronized block to the outside. We can use this restriction to prevent early writes from happening in critical sections of our code.

Another way of preventing early writes is to mark the field as volatile. We read in the Java Memory Model:

There is a happens-before edge from a write to a volatile variable v to all subsequent reads of v by any thread (where subsequent is defined according to the synchronization order)

This early writing is one of the reasons why the double-checked locking is broken in Java. The value of the field might get assigned before the constructor is called. Thus you might receive an uninitialised instance. A fix is to make the instance field volatile.

This law takes a bit of time to get your mind around. It is able to refute a lot of "clever" code that people have written to avoid synchronization.

Kind regards from Greece

Heinz

Concurrency 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.