[[ thread-safe.org ]]

Examples

A Simple Data Race

The following class has a data race for field f and therefore is not thread-safe. The check in method testAndUse() may succeed, but another thread may concurrently call toggle(), which sets f to null. As a result, the call to f.hashCode() will raise a NullPointerException.

package tso.examples;

import java.util.Random;

public class SimpleDataRace {

  private Object f = new Object();

  public void toggle() {
    if (f == null)
      f = new Object();
    else
      f = null;
  }

  public int testAndUse() {
    if (f != null)
      /* Potential NullPointerException:
       * f may become null before
       * calling hashCode()*/
      return new Random().nextInt() * f.hashCode();
    else
      return -1;
  }
}
See the checker's output for this example

A Simple Deadlock

The following class is not thread-safe, because using it may lead to a deadlock. The reason is that m1() and m2() both acquire lock1 and lock2, and that the two methods do it in reverse order. As a result, a thread that executes m1() will own lock1 and wait for lock2, while another thread that concurrently executes m2() will own lock2 and wait for lock1.

package tso.examples;

public class SimpleDeadlock {

  private Object lock1 = new Object();
  private Object lock2 = new Object();

  public void m1() {
    synchronized (lock1) {
      synchronized (lock2) {
        System.out.println("foo");
      }
    }		
  }

  public void m2() {
    synchronized (lock2) {
      synchronized (lock1) {
        System.out.println("bar");
      }
    }		
  }
}
See the checker's output for this example