Section 3.5.4 discusses about effectively immutable objects, that is, once an object is safely and fully constructed, its state would not be changed by any code of any code-path.
Sir Goetz has given an example:
For example,
Dateis mutable, but if you use it as if it were immutable you may be able to eliminate the locking that would otherwise be required when shared[sharing] a Date across threads. Suppose you want to maintain a Map storing the last login time of each user:public Map<String, Date> lastLogin = Collections.synchronizedMap(new HashMap<String, Date>());If the
Datevalues are not modified after they are placed in theMap, then the synchronization in thesynchronizedMapimplementation is sufficient to publish theDatevalues safely, and no additional synchronization is needed when accessing them.
The point that I am not able to understand is that why do we want to use synchronizedMap and bear the extra overhead of its internal lockings when we could have simply used unsafe Map, because after all we would be placing effectively immutable Date objects in it - which means, that once properly and fully constructed and published, it would not be mutated anymore. And so even if the Map itself be unsafe, there would be just no code in any of the code-paths which could concurrently mutate any Date instance while other thread(s) has retrieved it from the Unsafe Map.
To sum up, the very premise of effectively immutable objects does not necessitate need of any Thread-safe containers since we should just not have any mutator code in any code-path for effectively immutable objects.
Dateitself is immutable. But you are calling map.put() from multiple threads. Andmapis not immutable. You are adding it it. - fukanchikDateisn't immutable. What are you talking about? - MakotoDate is mutable, but if you use it as if it were immutable you may be able to eliminate the locking- fukanchikDateis infamously immutable; the phrasing you probably wanted to use was "effectively immutable". - Makoto