javamultithreadingfinal

Final object references - is visibility guaranteed between all threads?


I was reading this article:

https://www.javamex.com/tutorials/synchronization_final.shtml

It stated:

The fields on any object accessed via a final reference are also guaranteed to be at least as up to date as when the constructor exits. This means that: Values of final fields, including objects inside collections referred to by a final reference, can be safely read without synchronization.

Say I have a class as below:

public class Cache {


private Map<String, Currency> currencyMap = new ConcurrentHashMap<String, Currency>();
private List<Currency> currencyList = new ArrayList<Currency>();
}

If I declare in my main application class:

private final Cache cache;

Would that mean if Thread A updates currencyMap and currencyList, then this would guarantee Thread B will see the latest entries in currencyMap and currencyList?


Solution

  • There is no such guarantee that ThreadB will see the updates done to currencyList by the ThreadA. The guarantee that you achieve with

    private final Cache cache;
    

    is that the cache is safely published. Which means that the readers/other threads will observe the cache as a properly constructed object (in your case the currencyMap and currencyList will not be null and will be properly constructed).

    If ThreadA modifies the currencyList, there is no guarantee that the ThreadB will see the new values. You would have to synchronize access to the currencyList in order to achieve this.

    The currencyMap is a ConcurrentHashMap which is thread-safe class (the methods that change the state of the map are internally synchronized). If you never change the reference to the currencyMap (you will never assign some other map to that reference), then you don't have to synchronize the access to that map(because the cache is safely published), but better would be to declare the currencyMap as final (this will ensure that the reference will not be reassigned).