4

What does it mean to say that immutable objects can be published even without resorting to safe publication idioms?

I have read Java Concurrency in Practice (Chapter 3 , Sharing Objects) but still not able to comprehend the statement :

Immutable objects can be published through any mechanism.

               V/S 

Effectively immutable objects should be safely published.

Edit: I have been through a similar question on SO and the answers but still unable to understand how immutable objects can be published safely because there is a chance that the field referencing the immutable object will be seen as null or some stale value from earler invocations by an external thread.

Community
  • 1
  • 1
Geek
  • 26,489
  • 43
  • 149
  • 227
  • 1
    The immutable object itself can be published safely, any field that refer to it is not part of the immutable object and so does not have the same guarantees. – Trillian Jun 08 '13 at 14:44
  • They can't change, so you can think of them as "constants". For any constant you would expect to be able to publish without concurrency issues. – greedybuddha Jun 08 '13 at 14:44
  • @Trillian But in a language like Java what is the use of a safely published object if the reference to it is still stale? They should be in sync to say that the object has been safely published, right? – Geek Jun 08 '13 at 14:46
  • 1
    The issue? Thread safety, no less, no more. Immutable objects are _inherently thread safe_. This concept is so important that JSR 305 has an `@Immutable` annotation to decorate classes. – fge Jun 08 '13 at 14:48

1 Answers1

2

Not every use case needs to see a new instance at any precise moment. Consider the textbook example: lazily-initialized singletons which are cheaper to re-initialize in each thread than to share safely. In such a case you may unsafely share an immutable instance and each thread which doesn't manage to receive the already existent copy will just create its own.

As for terminology: unsafe publication means that it happens under a data race. Safe publication is the opposite case.

BTW java.lang.String is an example of an effectively immutable object which can nevertheless be shared unsafely.

Marko Topolnik
  • 195,646
  • 29
  • 319
  • 436
  • I have two follow up questions: 1)Why do you say that "*lazily initialized singletons are cheaper to reinitialize in each thread than to safely share*"? and 2)"*unsafe publication means that it happens under a data race*". What is a data-race in this context? – Geek Jun 08 '13 at 15:15
  • "*BTW java.lang.String is an example of an effectively immutable object which can nevertheless be shared unsafely.*"..Isn't String an exmaple of immutable and not effectively immutable? – Geek Jun 08 '13 at 15:20
  • 1
    String is not immutable because its `hashCode` property is mutable. It is effectively immutable because its publicly observable behavior is immutable. – Marko Topolnik Jun 09 '13 at 10:28
  • 1) I say "lazily initialized singletons which are cheaper..." as opposed to "lazily initialized singletons, which are cheaper...". Semantic difference: I constrain my subject to those lazy-init singletons which are cheap to initialize, as opposed to claiming that all lazy-init singletons are cheap to initialize. – Marko Topolnik Jun 09 '13 at 10:31
  • 2) The data race occurs on the variable holding the reference to the shared object. That variable is not `volatile` and its reads/writes occur under no coordination mechanism such as `synchronized` blocks. – Marko Topolnik Jun 09 '13 at 10:32
  • I do not understand why a singleton that can be cheaply initialized doesn't require to be safely published? Publish meaning " writing to a variable which another thread reads". In this case if the writing thread doesn't publish the singleton , safely , how would other threads see its most upto date value? if those other threads reinitialize the singleton how that operation is going to be any cheaper than publishing it safely in the first place? I have removed my thread local comment that added confusion. – Geek Jun 12 '13 at 11:11
  • Basically, you lack a good example where this makes sense. How about this: the singleton is used in a highly concurrent context, with a huge intensity of concurrent reads. The unbeatable performance of uncoordinated access is a deeply cherished goal. The singleton is either immutable or its current state can be cheaply reproduced. – Marko Topolnik Jun 12 '13 at 14:35
  • @MarkoTopolnik: It is necessary not only that the singleton be cheap to initialize, but also that it not encapsulate identity. If a singleton encapsulates identity, some mechanism must be used to ensure that only one thread will successfully publish a reference to an instance, and everyone else will see a reference to the instance created by the successful thread. – supercat Feb 08 '14 at 21:43
  • @supercat I think I see what you mean, but "encapsulate identity" isn't the right way to describe it since a) encapsulated state is not observable from the outside, which is precisely the *desired* property; b) it is impossible to encapsulate object identity. What we want is that object identity doesn't figure in object's API. – Marko Topolnik Feb 09 '14 at 11:01
  • @MarkoTopolnik: I would say that a reference :encapsulates identity" if it is possible that some other independent reference path might identify the same object, and the state represented by such a condition would be different from any state that could be represented if the references didn't identify the same object. Note that it is the references, rather than the object identified thereby, which encapsulate identity. Consider, for example, that an instance of `Object` doesn't really encapsulate any significant amount of data, but if a reference is used as a key in an `IdentityHashTable`... – supercat Feb 09 '14 at 16:42
  • ...then any other reference to that same object may be used to encapsulate an association with the "value" in the table. The reference itself wouldn't encapsulate anything other than the *identity* of an `Object`, and the `Object` wouldn't encapsulate anything other than its identity-hash value, but the fact that the object identified by the reference is the same object that appears in the table would allow code which knew of both references to recognize their association. – supercat Feb 09 '14 at 16:45