Tag Archives: thread safety

Java Tips: Thread Safety Documentation

Joshua Bloch in his book, “Effective Java” summarized the levels of thread safety:

  • immutable—Instances of this class appear constant. No external synchronization is necessary. Examples include String, Long, and BigInteger (Item 15).
  • unconditionally thread-safe—Instances of this class are mutable, but the class has sufficient internal synchronization that its instances can be used concurrently without the need for any external synchronization. Examples include Random and ConcurrentHashMap.
  • conditionally thread-safe—Like unconditionally thread-safe, except that some methods require external synchronization for safe concurrent use. Examples include the collections returned by the Collections.synchronized wrappers, whose iterators require external synchronization.
  • not thread-safe—Instances of this class are mutable. To use them concurrently, clients must surround each method invocation (or invocation sequence) with external synchronization of the clients’ choosing. Examples include the general-purpose collection implementations, such as ArrayList and HashMap.
  • thread-hostile—This class is not safe for concurrent use even if all method invocations are surrounded by external synchronization. Thread hostility usually results from modifying static data without synchronization. No one writes a thread-hostile class on purpose; such classes result from the failure to consider concurrency. Luckily, there are very few thread-hostile classes or methods in the Java libraries. The System.runFinalizersOnExit method is thread-hostile and has been deprecated.

Let we find a simplest example of classes for each of the mentioned level.

Immutable

public class ImmutableClass {

    private String a;

    public ImmutableClass(String a) {
        this.a = a;
    }

    public String getA() {
        return a;
    }

}

Unconditionally Thread Safe

public class UnconditionallyThreadSafeClass {

    private String a;

    private Object syncObject = new Object();

    public UnconditionallyThreadSafeClass(String a) {
        this.a = a;
    }

    public void setA(String a) {
        synchronized (syncObject) {
            this.a = a;
        }
    }

    public String getA() {
        synchronized (syncObject) {
            return a;
        }
    }

}

Conditionally Thread Safe

import java.util.ArrayList;

public class ConditionallyThreadSafeClass {

    private ArrayList<String> a;

    private Object syncObject = new Object();

    public ConditionallyThreadSafeClass(ArrayList<String> a) {
        this.a = a;
    }

    public void add(String s) {
        synchronized (syncObject) {
            a.add(s);
        }
    }

    public ArrayList<String> getA() {
        return a;
    }

}

Not Thread Safe

public class NotThreadSafeClass {

    private String a;

    public NotThreadSafeClass(String a) {
        this.a = a;
    }

    public String getA() {
        return a;
    }

    public void setA(String a) {
        this.a = a;
    }
}

Thread Hostile

public class ThreadHostileClass {

    private static String a;

    public ThreadHostileClass(String a) {
        ThreadHostileClass.a = a;
    }

    public String getA() {
        return a;
    }

    public void doSomethingToA(final String a) {
        new Thread() {
            public void run() {
                ThreadHostileClass.a = a;
            }
        }.run();
    }
}