I want to understand if volatile is needed to publish immutable objects.
For example, assuming we have an immutable object A:
// class A is immutable
class A {
final int field1;
final int field2;
public A(int f1, int f2) {
field1 = f1;
field2 = f2;
}
}
Then we have a class B that is accessed from different threads. It holds a reference to an object of class A:
// class B publishes object of class A through a public filed
class B {
private /* volatile? */ A toShare;
// this getter might be called from different threads
public A getA(){
return toShare;
}
// this might be called from different threads
public void setA(num1, num2) {
toShare = new A(num1, num2);
}
}
From my reading it seems immutable objects can be safely published through any means, so does that mean we don't need to declare toShare as volatile to ensure its memory visibility?
No, you are not guaranteed that you'll be seeing all updates to the toShare field of your shared data. This is because your shared data does not use any synchronization constructs that guarantee its visibility or the visibility of references reachable through it across threads. This makes it open game for numerous optimizations on the compiler and hardware level.
You can safely change your toShare field to reference a String (which is also immutable for all your purposes) and you'll probably (and correctly) feel more uneasy about its update visibility.
Here you can see a rudimentary example I've created that can show how updates are lost without any additional measures to publish changes to the reference of an immutable object. I've ran it using the -server JVM flag on JDK 8u65 and Intel® Core™ i5-2557M, disregarding the possibly thrown NullPointerException and saw the following results:
Without safe being volatile, the second thread doesn't terminate because it doesn't see many of the changes made by the first thread
Console output:
[T1] Shared data visible here is 2147483647
When safe is changed to be volatile, the second thread terminates alongside the first thread
Console output:
[T1] Shared data visible here is 2147483647
[T2] Last read value here is 2147483646
[T2] Shared data visible here is 2147483647
P.S. And a question to you - what happens if sharedData (and not safe) is made volatile? What could happen according to the JMM?
Answer is NO, it is needed to use volatile or any other way (for example, add synchronized keyword to both signatures get and set) to make a Happens/Before edge. Final fields semantic only guarantees that if someone sees a pointer to an instance of the class, all final fields have their values set according to constructor when it is finished:
http://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.5
And this says nothing about visibility of the reference itself. Since your example uses non-final field
private A toShare;
you have to take care about visibility of the field with volatile or synchronized section or a java.util.concurrent.locks.Locks or AtomicReference etc. to initiate/guarantee cache synchronization. Some useful stuff, BTW, about finals and safe publication http://shipilev.net/blog/2014/safe-public-construction/
http://shipilev.net/blog/2014/all-fields-are-final/
It seems like JMM should take care of the visibility problem for publishing immutable objects, at least that what's said in Concurrency in Practice, 3.5.2 Immutable Objects and Initialization Safely:
Because immutable objects are so important, the JavaMemory Model offers a special guarantee of initialization safety
for sharing immutable objects. As we've seen, that an object reference becomes visible to another thread does not
necessarily mean that the state of that object is visible to the consuming thread. In order to guarantee a consistent view
of the object's state, synchronization is needed.
Immutable objects, on the other hand, can be safely accessed even when synchronization is not used to publish the
object reference. For this guarantee of initialization safety to hold, all of the requirements for immutability must be met:
unmodifiable state, all fields are final, and proper construction.
Immutable objects can be used safely by any thread without additional synchronization, even when synchronization is
not used to publish them.
The following chapter 3.5.3 Safe publication Idioms states that safe publication is required only for non-immutable objects using the following approaches:
Static initializer
Storing reference in volatile/final/AtomicReference
Storing reference that is guarded by the lock
Related
I was reading Effective Java, and came across a condition where Joshua Bloch recommends something like
class MyComparator extends Comparator<String>{
private MyComparator(){}
private static final MyComparator INSTANCE = new MyComparator();
public int compare(String s1,String s2){
// Omitted
}
}
XYZComparator is stateless, it has no fields. hence all instances of the class are functionally equivalent. Thus it should be a singleton to save on unnecessary object creation.
So is it always safe to create a static final Object of whatever class it is pointing to if it has no fields? Wouldn't this cause multithreading issue when compare is called from two threads parallely? Or I misunderstood something basic. Is it like every thread has autonomy of execution if no fields is shared?
So is it always safe to create a static final Object of whatever class it is pointing to if it has no fields?
I would dare to say yes. Having no fields makes a class stateless and, thus, immutable, which is always desirable in a multithreading environment.
Stateless objects are always thread-safe.
Immutable objects are always thread-safe.
An excerpt from Java Concurrency In Practice:
Since the actions of a thread accessing a stateless object cannot affect the correctness of operations in other threads, stateless objects are thread-safe.
Stateless objects are always thread-safe.
The fact that most servlets can be implemented with no state greatly reduces the burden of making servlets threadͲ
safe. It is only when servlets want to remember things from one request to another that the thread-safety requirement becomes an issue.
...
An immutable object is one whose state cannot be changed after construction. Immutable objects are inherently
thread-safe; their invariants are established by the constructor, and if their state cannot be changed, these invariants
always hold.
Immutable objects are always thread-safe.
Immutable objects are simple. They can only be in one state, which is carefully controlled by the constructor. One of the
most difficult elements of program design is reasoning about the possible states of complex objects. Reasoning about
the state of immutable objects, on the other hand, is trivial.
Wouldn't this cause multithreading issue when compare is called from two threads parallelly?
No. Each thread has own stack where local variables (including method parameters) are stored. The thread's stack isn't shared, so there is no way to mess it up parallelly.
Another good example would be a stateless servlet. One more extract from that great book.
#ThreadSafe
public class StatelessFactorizer implements Servlet {
public void service(ServletRequest req, ServletResponse resp) {
BigInteger i = extractFromRequest(req);
BigInteger[] factors = factor(i);
encodeIntoResponse(resp, factors);
}
}
StatelessFactorizer is, like most servlets, stateless: it has no fields and references no fields from other classes. The
transient state for a particular computation exists solely in local variables that are stored on the thread's stack and are
accessible only to the executing thread. One thread accessing a StatelessFactorizer cannot influence the result of
another thread accessing the same StatelessFactorizer; because the two threads do not share state, it is as if they
were accessing different instances.
Is it like every thread has autonomy of execution if no fields is shared?
Each thread has its own program counter, stack, and local variables. There is a term "thread confinement" and one of its forms is called "stack confinement".
Stack confinement is a special case of thread confinement in which an object can only be reached through local variables. Just as encapsulation can make it easier to preserve invariants, local variables can make it easier to confine objects to a thread. Local variables are intrinsically confined to the executing thread; they exist on the executing thread's stack, which is not accessible to other threads.
To read:
Java Concurrency In Practice
Thread Confinement
Stack Confinement using local object reference
Multithreading issues are caused by unwanted changes in state. If there is no state that is changed, there are no such issues. That is also why immutable objects are very convenient in a multithreaded environment.
In this particular case, the method only operates on the input parameters s1 and s2 and no state is kept.
So is it always safe to create a static final Object of whatever class it is pointing to if it has no fields?
"Always" is too strong a claim. It's easy to construct an artificial class where instances are not thread-safe despite having no fields:
public class NotThreadSafe {
private static final class MapHolder {
private static final Map<NotThreadSafe, StringBuilder> map =
// use ConcurrentHashMap so that different instances don't
// interfere with each other:
new ConcurrentHashMap<>();
}
private StringBuilder getMyStringBuilder() {
return MapHolder.map.computeIfAbsent(this, k -> new StringBuilder());
}
public void append(final Object s) {
getMyStringBuilder().append(s);
}
public String get() {
return getMyStringBuilder().toString();
}
}
. . . but that code is not realistic. If your instances don't have any mutable state, then they'll naturally be threadsafe; and in normal Java code, mutable state means instance fields.
XYZComparator is stateless, it has no fields. hence all instances of the class are functionally equivalent. Thus it should be a singleton to save on unnecessary object creation.
From that point of view, the "current day" answer is probably: make MyComparator an enum. The JVM guarantees that MyComparatorEnum.INSTANCE will be a true singelton, and you don't have to worry about the subtle details that you have to consider when building singletons "yourself".
Explanation
So is it always safe to create a static final Object of whatever class it is pointing to if it has no fields?
Depends. Multi-threading issues can only occur when one thread is changing something while another thread is using it at the same time. Since the other thread might then not be aware of the changes due to caching and other effects. Or it results in a pure logic bug where the creator did not think about that a thread can be interrupted during an operation.
So when a class is stateless, which you have here, it is absolutely safe to be used in a multi-threaded environment. Since there is nothing for any thread to change in the first place.
Note that this also means that a class is not allowed to use not-thread-safe stuff from elsewhere. So for example changing a field in some other class while another thread is using it.
Example
Here is a pretty classic example:
public class Value {
private int value;
public int getValue() {
return value;
}
public void increment() {
int current = value; // or just value++
value = current + 1;
}
}
Now, lets assume both threads call value.increment(). One thread gets interrupted after:
int current = value; // is 0
Then the other starts and fully executes increment. So
int current = value; // is 0
value = current + 1; // is 1
So value is now 1. Now the first thread continues, the expected outcome would be 2, but we get:
value = current + 1; // is 1
Since its current was already computed before the second thread ran through, so it is still 0.
We also say that an operation (or method in this case) is not atomic. So it can be interrupted by the scheduler.
This issue can of course only happen because Value has a field value, so it has a changeable state.
YES. It is safe to create a static final object of a class if it has no fields. Here, the Comparator provides functionality only, through its compare(String, String) method.
In case of multithreading, the compare method will have to deal with local variables only (b/c it is from stateless class), and local variables are not shared b/w thread, i.e., each thread will have its own (String, String) copy and hence will not interfere with each other.
Calling the compare method from two threads in parallel is safe (stack confinement). The parameters you pass to the method are stored in that thread's stack, that any other thread cannot access.
An immutable singleton is always recommended. Abstain from creating mutable singletons, as they introduce global state in your application, that is bad.
Edit: If the params passed are mutable object references, then you have to take special care to ensure thread safety.
I have been working on a daily basis with the Java Memory Model for some years now. I think I have a good understanding about the concept of data races and the different ways to avoid them (e.g, synchronized blocks, volatile variables, etc). However, there's still something that I don't think I fully understand about the memory model, which is the way that final fields of classes are supposed to be thread safe without any further synchronization.
So according to the specification, if an object is properly initialized (that is, no reference to the object escapes in its constructor in such a way that the reference can be seen by another thread), then, after construction, any thread that sees the object will be guaranteed to see the references to all the final fields of the object (in the state they were when constructed), without any further synchronization.
In particular, the standard (http://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.4) says:
The usage model for final fields is a simple one: Set the final fields
for an object in that object's constructor; and do not write a
reference to the object being constructed in a place where another
thread can see it before the object's constructor is finished. If this
is followed, then when the object is seen by another thread, that
thread will always see the correctly constructed version of that
object's final fields. It will also see versions of any object or
array referenced by those final fields that are at least as up-to-date
as the final fields are.
They even give the following example:
class FinalFieldExample {
final int x;
int y;
static FinalFieldExample f;
public FinalFieldExample() {
x = 3;
y = 4;
}
static void writer() {
f = new FinalFieldExample();
}
static void reader() {
if (f != null) {
int i = f.x; // guaranteed to see 3
int j = f.y; // could see 0
}
}
}
In which a thread A is supposed to run "reader()", and a thread B is supposed to run "writer()".
So far, so good, apparently.
My main concern has to do with... is this really useful in practice? As far as I know, in order to make thread A (which is running "reader()") see the reference to "f", we must use some synchronization mechanism, such as making f volatile, or using locks to synchronize access to f. If we don't do so, we are not even guaranteed that "reader()" will be able to see an initialized "f", that is, since we have not synchronized access to "f", the reader will potentially see "null" instead of the object that was constructed by the writer thread. This issue is stated in http://www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html#finalWrong , which is one of the main references for the Java Memory Model [bold emphasis mine]:
Now, having said all of this, if, after a thread constructs an
immutable object (that is, an object that only contains final fields),
you want to ensure that it is seen correctly by all of the other
thread, you still typically need to use synchronization. There is no
other way to ensure, for example, that the reference to the immutable
object will be seen by the second thread. The guarantees the program
gets from final fields should be carefully tempered with a deep and
careful understanding of how concurrency is managed in your code.
So if we are not even guaranteed to see the reference to "f", and we must therefore use typical synchronization mechanisms (volatile, locks, etc.), and these mechanisms do already cause data races to go away, the need for final is something I would not even consider. I mean, if in order to make "f" visible to other threads we still need to use volatile or synchronized blocks, and they already make internal fields be visible to the other threads... what's the point (in thread safety terms) in making a field final in the first place?
I think that you are misunderstanding what the JLS example is intended to show:
static void reader() {
if (f != null) {
int i = f.x; // guaranteed to see 3
int j = f.y; // could see 0
}
}
This code does not guarantee that the latest value of f will be seen by the thread that calls reader(). But what it is saying is that if you do see f as non-null, then f.x is guaranteed to be 3 ... despite the fact that we didn't actually do any explicit synchronizing.
Well is this implicit synchronization for finals in constructors useful? Certainly it is ... IMO. It means that we don't need to do any extra synchronization each time we accessed an immutable object's state. That is a good thing, because synchronization typically entails cache read-through or write-through, and that slows your program down.
But what Pugh is saying is that you will typically need to synchronize to get hold of the reference to the immutable object in the first place. He is making the point that using immutable objects (implemented using final) does not excuse you from the need to synchronize ... or from the need to understand the concurrency / synchronization implementation of your application.
The problem is that we still need to be sure that reader will se a non-null "f", and that's only possible if we use other synchronization mechanism that will already provide the semantics of allowing us to see 3 for f.x. And if that's the case, why bother using final for thread safety stuff?
There is a difference between synchronizing to get the reference and synchronizing to use the reference. The first one I may need to do only once. The second one I may need to do lots of times ... with the same reference. And even if it is one-to-one, I have still halved the number of synchronizing operations ... if I (hypothetically) implement the immutable object as thread-safe.
TL;DR: Most software developers should ignore the special rules regarding final variables in the Java Memory Model. They should adhere to the general rule: If a program is free of data races, all executions will appear to be sequentially consistent. In most cases, final variables can not be used to improve the performance of concurrent code, because the special rule in the Java Memory Model creates some additional costs for final variables, what makes volatile superior to final variables for almost all use cases.
The special rule about final variables prevents in some cases, that a final variable can show different values. However, performance-wise the rule is irrelevant.
Having said that, here is a more detailed answer. But I have to warn you. The following description might contain some precarious information, that most software developers should never care about, and it's better if they don't know about it.
The special rule about final variables in the Java Memory Model somehow implies, that it makes a difference for the Java VM and Java JIT compiler, if a member variable is final or if it's not.
public class Int {
public /* final */ int value;
public Int(int value) {
this.value = value;
}
}
If you take a look at the Hotspot source code, you will see that the compiler checks if the constructor of a class writes at least one final variable. If it does so, the compiler will emit additional code for the constructor, more precisely a memory release barrier. You will also find the following comment in the source code:
This method (which must be a constructor by the rules of Java)
wrote a final. The effects of all initializations must be
committed to memory before any code after the constructor
publishes the reference to the newly constructor object.
Rather than wait for the publication, we simply block the
writes here. Rather than put a barrier on only those writes
which are required to complete, we force all writes to complete.
That means the initialization of a final variable is similar to a write of a volatile variable. It implies some kind of memory release barrier. However, as can be seen from the quoted comment, final variables might be even more expensive. And what's even worse, you have these additional costs for final variables regardless whether they are used in concurrent code or not.
That's awful, because we want software developers to use final variables in order to increase the readability and maintainability of source code. Unfortunately, using final variables can significantly impact the performance of a program.
The question remains: Are there any use cases where the special rule regarding final variables helps to improve the performance of concurrent code?
That's hard to tell, because it depends on the actual implementation of the Java VM and the memory architecture of the machine. I haven't seen any such use cases until now. A quick glance at the source code of the package java.util.concurrent has also revealed nothing.
The problem is: The initialization of a final variable is about as expensive as a write of a volatile or atomic variable. If you use a volatile variable for the reference of the newly created object, you get the same behaviour and costs with the exception, that the reference will also be published immediately. So, there is basically no benefit in using final variables for concurrent programming.
You are right, since locking makes stronger guarantees, the guarantee about availability of finals is not particularly useful in the presence of locking. However, locking is not always necessary to ensure reliable concurrent access.
As far as I know, in order to make thread A (which is running "reader()") see the reference to "f", we must use some synchronization mechanism, such as making f volatile, or using locks to synchronize access to f.
Making f volatile is not a synchronization mechanism; it forces threads to read the memory each time the variable is accessed, but it does not synchronize access to a memory location. Locking is a way to synchronize access, but it is not necessary in practice to guarantee that the two threads share data reliably. For example, you could use a ConcurrentLinkedQueue<E> class, which is a lock-free concurrent collection* , to pass data from a reader thread to a writer thread, and avoid synchronization. You could also use AtomicReference<T> to ensure reliable concurrent access to an object without locking.
It is when you use lock-free concurrency that the guarantee about the visibility of final fields come in handy. If you make a lock-free collection, and use it to store immutable objects, your threads would be able to access the content of the objects without additional locking.
* ConcurrentLinkedQueue<E> is not only lock-free, but also a wait-free collection (i.e. a lock-free collection with additional guarantees not relevant to this discussion).
Yes final final fields are useful in terms of thread-safety. It may not be useful in your example, however if you look at the old ConcurrentHashMap implementation the get method doesn't apply any locking while it search for the value, though there is a risk that while look up is happening the list might change (think of ConcurrentModificationException ). However CHM uses the list made of final filed for 'next' field guaranteeing the consistency of the list (the items in the front/yet-to see will not grow or shrink). So the advantage is thread-safety is established without synchronization.
From the article
Exploiting immutability
One significant source of inconsistency is avoided by making the Entry
elements nearly immutable -- all fields are final, except for the
value field, which is volatile. This means that elements cannot be
added to or removed from the middle or end of the hash chain --
elements can only be added at the beginning, and removal involves
cloning all or part of the chain and updating the list head pointer.
So once you have a reference into a hash chain, while you may not know
whether you have a reference to the head of the list, you do know that
the rest of the list will not change its structure. Also, since the
value field is volatile, you will be able to see updates to the value
field immediately, greatly simplifying the process of writing a Map
implementation that can deal with a potentially stale view of memory.
While the new JMM provides initialization safety for final variables,
the old JMM does not, which means that it is possible for another
thread to see the default value for a final field, rather than the
value placed there by the object's constructor. The implementation
must be prepared to detect this as well, which it does by ensuring
that the default value for each field of Entry is not a valid value.
The list is constructed such that if any of the Entry fields appear to
have their default value (zero or null), the search will fail,
prompting the get() implementation to synchronize and traverse the
chain again.
Article link: https://www.ibm.com/developerworks/library/j-jtp08223/
I want to make sure that I correctly understand the 'Effectively Immutable Objects' behavior according to Java Memory Model.
Let's say we have a mutable class which we want to publish as an effectively immutable:
class Outworld {
// This MAY be accessed by multiple threads
public static volatile MutableLong published;
}
// This class is mutable
class MutableLong {
private long value;
public MutableLong(long value) {
this.value = value;
}
public void increment() {
value++;
}
public long get() {
return value;
}
}
We do the following:
// Create a mutable object and modify it
MutableLong val = new MutableLong(1);
val.increment();
val.increment();
// No more modifications
// UPDATED: Let's say for this example we are completely sure
// that no one will ever call increment() since now
// Publish it safely and consider Effectively Immutable
Outworld.published = val;
The question is:
Does Java Memory Model guarantee that all threads MUST have Outworld.published.get() == 3 ?
According to Java Concurrency In Practice this should be true, but please correct me if I'm wrong.
3.5.3. Safe Publication Idioms
To publish an object safely, both the reference to the object and the
object's state must be made visible to other threads at the same time.
A properly constructed object can be safely published by:
- 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.
3.5.4. Effectively Immutable Objects
Safely published effectively immutable objects can be used safely by
any thread without additional synchronization.
Yes. The write operations on the MutableLong are followed by a happens-before relationship (on the volatile) before the read.
(It is possible that a thread reads Outworld.published and passes it on to another thread unsafely. In theory, that could see earlier state. In practice, I don't see it happening.)
There is a couple of conditions which must be met for the Java Memory Model to guarantee that Outworld.published.get() == 3:
the snippet of code you posted which creates and increments the MutableLong, then sets the Outworld.published field, must happen with visibility between the steps. One way to achieve this trivially is to have all that code running in a single thread - guaranteeing "as-if-serial semantics". I assume that's what you intended, but thought it worth pointing out.
reads of Outworld.published must have happens-after semantics from the assignment. An example of this could be having the same thread execute Outworld.published = val; then launch other the threads which could read the value. This would guarantee "as if serial" semantics, preventing re-ordering of the reads before the assignment.
If you are able to provide those guarantees, then the JMM will guarantee all threads see Outworld.published.get() == 3.
However, if you're interested in general program design advice in this area, read on.
For the guarantee that no other threads ever see a different value for Outworld.published.get(), you (the developer) have to guarantee that your program does not modify the value in any way. Either by subsequently executing Outworld.published = differentVal; or Outworld.published.increment();. While that is possible to guarantee, it can be so much easier if you design your code to avoid both the mutable object, and using a static non-final field as a global point of access for multiple threads:
instead of publishing MutableLong, copy the relevant values into a new instance of a different class, whose state cannot be modified. E.g.: introduce the class ImmutableLong, which assigns value to a final field on construction, and doesn't have an increment() method.
instead of multiple threads accessing a static non-final field, pass the object as a parameter to your Callable/Runnable implementations. This will prevent the possibility of one rogue thread from reassigning the value and interfering with the others, and is easier to reason about than static field reassignment. (Admittedly, if you're dealing with legacy code, this is easier said than done).
The question is: Does Java Memory Model guarantee that all threads
MUST have Outworld.published.get() == 3 ?
The short answer is no. Because other threads might access Outworld.published before it has been read.
After the moment when Outworld.published = val; had been performed, under condition that no other modifications done with the val - yes - it always be 3.
But if any thread performs val.increment then its value might be different for other threads.
Let's say I have this class:
class Zoo
{
protected String bearName;
protected Double trainerSalary;
protected Integer monkeyCount;
}
Can one thread write to these fields, and another one read them, without requiring synchronized access to the Zoo object?
Note: these values can be treated separate from one another, so it doesn't matter that the trainerSalary is changed while the monkeyCount is read.
EDIT:
Just to clarify, the fields are mutable; only their referenced objects are immutable.
Technically you need to make them final, volatile or read and write them using synchronzied to guarantee that the reader will read the most up-to-date value. As you have it right now, if one thread writes in a value, there's no guarantee that another thread will read the same value. This is because the the reading thread may see a cached valued. This is more likely with multi-core CPUs and various levels of cache.
A great book on this is Java Concurrency in Practice.
Accesses and updates to the memory cells corresponding to fields of any type except long or double are guaranteed to be atomic (see Concurrent Programming In Java). That's why one might expect that you don't need to synchronize read access to your fields. However, the Java memory model allows threads to cache previously read values in case you access them repeatedly so you should mark the fields as volatile to ensure that each thread sees the most recent values.
If you are sure that nobody will change the values of the fields, make them final. In that case, no volatile field is necessary.
Things are different if the values of the fields depend on each other. In that case, I'd recommend to use synchronized setters that ensure that the invariant of your class is not violated.
As you've stated the class it's possible for another class in the same package to change these values. This class isn't immutable.
Now if you did something like
class Zoo
{
protected final String bearName;
protected final Double trainerSalary;
protected final Integer monkeyCount;
}
Then the class would be immutable. If the logic of your program treats this class as immutable, then why not make it actually immutable?
Also, if multiple threads were checking and updating the same value then you could have issue. Say multiple threads were checking and updating monkeyCount, then there is a good chance monkeyCount would end up incorrect because there is nothing that is forcing these check and updates to occur atomically.
My 2 cents, from "The Java Programming Language", 4 ed., 14.10.2 :
"There is a common misconception that shared access to immutable objects does not require any synchronization because the state of the object never changes. This is a misconception in general because it relies on the assumption that a thread will be guaranteed to see the
initialized state of the immutable object, and that need not be the case. The problem is that, while the shared object is immutable, the reference used to access the shared object is itself shared and often mutable - consequently, a correctly synchronized program must synchronize access to that shared reference, but often programs do not do this, because programmers do not recognize the need to do it. For example, suppose one thread creates a String object and stores a reference to it in a static field. A second thread then uses that
reference to access the string. There is no guarantee, based on what we've discussed so far, that the values written by the first thread when constructing the string will be seen by the second thread when it accesses the string."
If those variables are indeed independent, then no, you do not need synchronization. However, as you note, if you had
protected Integer monkeysLeft;
protected Integer monkeysEatenByBears;
where the two variables are logically connected, you would want synchronized access to the pair of them.
I came across this statement:
In properly constructed objects, all
threads will see correct values of
final fields, regardless of how the
object is published.
Then why a volatile variable is used to safely
publishing an Immutable object?
I'm really confused. Can anybody make it clear with a suitable example?
In this case, the volatility would only ensure visibility of the new object; any other threads that happened to get hold of your object via a non-volatile field would indeed see the correct values of final fields as per JSR-133's initialization safety guarantees.
Still, making the variable volatile doesn't hurt; is correct from a memory management perspective anyway; and would be necessary for non-final fields initialised in a constructor (although there shouldn't be any of these in an immutable object). If you wish to share variables between threads, you'll need to ensure adequate synchronization to give visibility anyway; though in this case you're right, that there's no danger to the atomicity of the constructor.
Thanks to Tom Hawtin for pointing out I'd completely overlooked the JMM guarantees on final fields; previous incorrect answer is given below.
The reason for the volatile variable is that is establishes a happens-before relationship (according to the Java Memory Model) between the construction of the object, and the assignment of the variable. This achieves two things:
Subsequent reads of that variable from different threads are guaranteed to see the new value. Without marking the variable as volatile, these threads could see stale values of the reference.
The happens-before relationship places limits on what reorderings the compiler can do. Without a volatile variable, the assignment to the variable could happen before the object's constructor runs - hence other threads could get a reference to the object before it was fully constructed.
Since one of the fundamental rules of immutable objects is that you don't publish references during the constructor, it's this second point that is likely being referenced here. In a multithreaded environment without proper concurrent handling, it is possible for a reference to the object to be "published" before that object has been constructed. Thus another thread could get that object, see that one of its fields is null, and then later see that this "immutable" object has changed.
Note that you don't have to use volatile fields to achieve this if you have other appropriate synchronization primitives - for example, if the assignment (and all later reads) are done in a synchronized block on a given monitor - but in a "standalone" sense, marking the variable as volatile is the easiest way to tell the JVM "this might be read by multiple threads, please make the assignment safe in that context."
A volatile reference to an immutable object could be useful. This would allow you to swap one object for another to make the new data available to other threads.
I would suggets you look at using AtomicReference first however.
If you need final volatile fields you have a problem. All fields, including final ones are available to other threads as soon as the constructor returns. So if you pass an object to another thread in the constructor, it is possible for the other thread to see an inconsistent state. IMHO you should consider a different solution so you don't have to do this.
You cant really see the difference in Immutable class.see the below example.in Myclass.class
public static Foo getInstance(){
if(INSTANCE == null){
INSTANCE = new Foo();
}
return INSTANCE;
}
in the above code if Foo is declared final(final Foo INSTANCE;) it guarantees that it won't publish references during the constructor call.partial object construction is not possible
consider this...if this Myclass is Immutable, its state is not gonna change after object construction, making Volatile(volatile final Foo INSTANCE;) keyword redundant.but if this class allows its object state to be changed(Not immutable) multiple threads CAN actually update the object and some updates are not visible to other threads, hence volatile keyword ensures safety publication of objects in non-Immutable class.