final fields and thread-safety

10,545

In order to use an effectively immutable object without final fields in a thread safe manner you need to use one of safe publication idioms when making the object available to other threads after initialization, otherwise these threads can see the object in partially initialized state (from Java Concurrency in Practice):

  • Initializing an object reference from a static initializer;
  • Storing a reference to it into a volatile field or AtomicReference;
  • Storing a reference to it into a final field of a properly constructed object; or
  • Storing a reference to it into a field that is properly guarded by a lock.

Declaring fields of your immutable object as final releases this restriction (i.e. it guarantees that if other threads see a reference to the object, they also see its final fields in fully initialized state). However, in general case it doesn't guarantee that other threads can see a reference to the object as soon as it was published, so you may still need to use safe publication to ensure it.

Note that if your object implements an interface, you can use an approach used by Collections.unmodifiableList(), etc:

class ImmutableFooWrapper implements IFoo {
    private final IFoo delegate; // final provides safe publication automatically

    public ImmutableFooWrapper(IFoo delegate) {
        this.delegate = delegate;
    }
    ...
}

public IFoo immutableFoo(IFoo foo) {
    return new ImmutableFooWrapper(foo);
}
Share:
10,545

Related videos on Youtube

pcjuzer
Author by

pcjuzer

Java, JS, Android full stack developer for a living. Father. Amateur trail trunner, wannabe startupper.

Updated on June 08, 2022

Comments

  • pcjuzer
    pcjuzer almost 2 years

    Should it be all fields, including super-fields, of a purposely immutable java class 'final' in order to be thread-safe or is it enough to have no modifier methods?

    Suppose I have a POJO with non-final fields where all fields are type of some immutable class. This POJO has getters-setters, and a constructor which sets some initial value. If I extend this POJO with knocking out modifier methods, thus making it immutable, will extension class be thread-safe?

    • Tomasz Nurkiewicz
      Tomasz Nurkiewicz over 12 years
      What do you mean by knocking out modifier methods modifier methods? Throwing an exception from all setters? This would violate Liskov substitution principle. But yes, this class would be thread-safe.
  • pcjuzer
    pcjuzer over 12 years
    Thanks for your detailed answer. I was thinking about the same solution with using delegate but then I always returned to the solution with extension, because I guess 'super' reference is also final. What do I miss?
  • axtavt
    axtavt over 12 years
    @pcjuzer: super has nothing to do with concurrency, so that in the case of extension you would need safe publication anyway.
  • AlexLiesenfeld
    AlexLiesenfeld about 11 years
    Why do the fields actually have to be private?
  • AKS
    AKS over 10 years
    So, that means if you are declaring a field final then if it is being updated by one thread then other thread will not see it and if it sees then it will see in updated state?