Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

final fields and thread-safety

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?

like image 931
pcjuzer Avatar asked Aug 22 '11 08:08

pcjuzer


People also ask

Are final fields thread-safe?

Final variables are immutable references, so a variable declared final is safe to access from multiple threads. You can only read the variable, not write it.

Is final keyword thread-safe?

Yes, 100% safe. It's final, so nobody can alter it.

What is a final field?

A final field is one that cannot be changed once it is initialized. This means slightly different things for primitive and class types. We create final fields by declaring them with the final keyword. We cannot change the value of a final primitive field ( final int , final double , etc.) after it is initialized.

Is final thread-safe Java?

1) Immutable objects are by default thread-safe because their state can not be modified once created. Since String is immutable in Java, it's inherently thread-safe. 2) Read-only or final variables in Java are also thread-safe in Java.


1 Answers

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);
}
like image 73
axtavt Avatar answered Oct 12 '22 19:10

axtavt