From the book Java Concurrency In Practice:
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.
My question is:
Why does the bullet point 3 have the constrain:"of a properly constructed object", but the bullet point 2 does not have?
Does the following code safely publish the map instance? I think the code meets the conditions of bullet point 2.
public class SafePublish {
volatile DummyMap map = new DummyMap();
SafePublish() throws InterruptedException {
new Thread(new Runnable() {
#Override
public void run() {
// Safe to use 'map'?
System.out.println(SafePublish.this.map);
}
}).start();
Thread.sleep(5000);
}
public static void main(String[] args) throws InterruptedException {
SafePublish safePublishInstance = new SafePublish();
}
public class DummyMap {
DummyMap() {
System.out.println("DummyClass constructing");
}
}
}
The following debug snapshot pic shows the map instance is null at the time of the execution is entering the construction of SafePublish. What happens if another thread now trying to read the map reference? Is it safe to read?
It's because final fields are guaranteed to be visible to other threads only after the object construction while the visibility of writes to volatile fields are guaranteed without any additional conditions.
From jls-17, on final fields:
An object is considered to be completely initialized when its constructor finishes. A thread that can only see a reference to an object after that object has been completely initialized is guaranteed to see the correctly initialized values for that object's final fields.
on volatile fields:
A write to a volatile variable v (§8.3.1.4) synchronizes-with all subsequent reads of v by any thread (where "subsequent" is defined according to the synchronization order).
Now, regarding your specific code example, JLS 12.5 guarantees that field initialization occurs before the code in your constructor is executed (see steps 4 and 5 in JLS 12.5, which is a bit too long to quote here). Therefore, Program Order guarantees that the constructor's code will see map initialized, regardless of whether it's volatile or final or just a regular field. And since there's a Happens-Before relation before field writes and the start of a thread, even the thread you're creating in the constructor will see map as initialized.
Note that I specifically wrote "before code in your constructor is executed" and not "before the constructor is executed" because that's not the guarantee JSL 12.5 makes (read it!). That's why you're seeing null in the debugger before the first line of the constructor's code, yet the code in your constructor is guaranteed to see that field initialized.
Related
I'm reading "Java concurrency in practice", and it says:
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.
What I don't understand is "Storing a reference to it into a final field of a properly constructed object", Why is "of a properly constructed object" needed? Without "of a properly constructed object", can other threads see the object that is being published in an inconsistent state?
I have read several related questions:
final vs volatile guaranntee w.rt to safe publication of objects - Stack Overflow
safe publication of mutable object - Stack Overflow
But I can't find much explanation about Why "of a properly constructed object" is needed.
Below example comes from an answer in question "final vs volatile guaranntee w.rt to safe publication of objects - Stack Overflow"
class SomeClass{
private final SomeType field;
SomeClass() {
new Thread(new Runnable() {
public void run() {
SomeType copy = field; //copy could be null
copy.doSomething(); //could throw NullPointerException
}
}).start();
field = new SomeType();
}
}
SomeClass is not properly constructed, of course, copy could be null, but in my opinion, the thread can not see the copy in an inconsistent state, either copy is null or "both the reference to the copy and the copy's state must be made visible to the threads at the same time". So, field is published safely even though SomeClass is not properly constructed. Am I right?
Hope someone can give me more explanation, thanks in advance.
It depends on what you call "consistent state". If seeing a null pointer where a published object should be, i.e. the object actually looks as if it was not published, counts as "consistent" then you're right in that the example produces "consistency".
Do note however that final fields are supposed to not change their value. If a thread reads from a final it can safely assume that the field's value will not change later. The thread's implementation, or the (JIT) compiler, may 'cache' the field's value in some variable (or register) because final tells it that the value read once stays the same.
Specifically, code like
new Thread(new Runnable() {
public void run() {
while ( field == null ) {
// Wait a little...
}
// Field was initialized, go ahead.
}
}).start();
Will probably only have two possible outcomes: Either the loop is never entered, or it becomes an infinite loop.
That's why it is especially not safe to access a final field before it is initialized; and final fields are only guaranteed to be initialized after the constructor completed.
The issue may become more apparent if you write the fully qualified field name in the thread's code, which is SomeClass.this.field. You are allowed to omit it but the compiler will implicitly generate the proper access for you. Using the fully qualified field name you can see more clearly that the thread accesses SomeClass.this.field before this is fully initialized. So, effectively, you don't actually publish the consistent SomeType object but the still inconsistent SomeClass object which happens to contain that field.
I am recently reading the book "Java Concurrency in Practice". One example of "safe publish" it gives is to initialize a private int field n during construction, and a later assertion on that field n == "expect value" through a public method could still be failed if it is called from another thread. This makes me feel worried in that, assuming all private fields are initialized only once, do we still have to mark them as volatile or wrap them into ThreadLocal or even use an AtomicReference to get a pure thread safe java class, since these private fields, though not visible outside, definitely could be referenced by the method(s) called by other threads.
EDIT: Just to be clear - the assertion is failed because the calling thread sees a stale value of n, even though it has been set during construction. This is a clearly a memory-visibility issue. Problem is whether synchronizing on n is worthy of the overhead after all, since it is only initialized once, and as a private field, author can make sure it won't be changed again.
This specific case is properly documented in the JSR 133: Java Memory Model and Thread
Specification. It even has a dedicated code sample page 14 section 3.5 Final Fields that exactly match your question.
To summarize:
A thread that can only see a reference to an object after that object has been completely initialized is guaranteed to see the correctly initialized values for that object’s final fields.
There is no guarantee for non final fields
It means that you have to make sure that an happens-before occurs between your object creation in a thread and its usage in another thread. You can use synchronized, volatile or any other mean to enforce an happens-before.
Since you say in another comment that the field is only set during construction, I would make it... final. Also, such shared objects between threads could suggest some design smell; I would review my design to make sure that I am not creating an overly complex, tightly coupled, hard to debug system.
If the fields are never used outside the class, wrapping their usages with synchronized blocks or inside synchronized functions, two threads won't concurrently modify these fields.
volatile keyword is just a part of thread safety. It only makes the value of a field never be cached, always read from memory. Take this example.
private int myPrivateField = 0;
void someFunction() {
while(myPrivateField ==0) {
}
}
void otherFunction() {
myPrivateField = 1;
}
If someFunction() is called from one thread and it's running for a while,
when you call otherFunction() the value of myPrivateField will not be
"updated" inside someFunction, it was cached to 0 as an otimization.
Making myPrivateField as volatile, the value will always be the one
in memory.
For the example, there won't be much difference for the functions be
synchronized, but without synchronization, you can read a value in an
inconsistent state.
Only final fields are guaranteed to be visible after constructor. Any other field requires some visibility mechanism, such as synchronized or volatile.
This is not as much of a burden as it seems: if the field is not final, then it can be changed by another thread while you're reading it. If teh field can be changed, then the last assigned value must be propagated from the writer thread to the reader thread, whether the writer thread called the constructor or a setter.
If the change in this field is not related to any other field in the class, then the field should be volatile. If the field is related to other fields in the class, then use synchronized or other, more modern locking primitives.
Not answering the entire question, but it should be pointed out that using ThreadLocal is exactly the wrong thing to use if you want to ensure visibility of updated values in all threads. Consider the following code:
class Test {
private static final ThreadLocal<Integer> value = new ThreadLocal<>();
public static void main(String[] args) throws InterruptedException {
System.out.println("From main Thread, value is " + value.get());
value.set(42);
System.out.println("Value has been changed");
Thread t = new Thread() {
public void run() {
System.out.println("From other Thread, value is " + value.get());
}
};
t.start();
t.join();
System.out.println("From main Thread, value is " + value.get());
}
}
This will output the following:
From main Thread, value is null
Value has been changed
From other Thread, value is null
From main Thread, value is 42
i.e. the other thread doesn't see the updated value. This is because changes to the value of a ThreadLocal is, by definition, localized to the thread which changes it.
My personal preference would be to use AtomicReference, since this avoids the risk of forgetting to synchronize externally; it also allows things like atomic compare-and-set, which you don't get with a volatile variable. However, this may not be a requirement for your particular application.
Let's say I have a JavaBean User that's updated from another thread like this:
public class A {
private final User user;
public A(User user) {
this.user = user;
}
public void aMethod() {
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
...a long running task..
user.setSomething(something);
}
});
t.start();
t.join();
}
public void anotherMethod() {
GUIHandler.showOnGuiSomehow(user);
}
}
Is this code thread safe? I mean, when the thread that created A instance and called A.aMethod reads user fields, does it see user in the fresh state? How to do it in appropriate thread safe manner?
Note that I can't modify the user class and I don't know if it's thread safe itself.
Is this code thread safe? ... does it see user in the fresh state?
Not especially - the fact that user is final in your code makes almost no difference to thread safety other than the fact that it cannot be replaced.
The bit that should change is the instance variable that is set by setSomething. It should be marked as volatile.
class User {
// Marked `volatile` to ensure all writes are visible to other threads.
volatile String something;
public void setSomething(String something) {
this.something = something;
}
}
If however (as you suggest) you do not have access to the User class, you must then perform a synchronization that creates a memory barrier. In its simplest form you could surround your access to the user with a synchronized access.
synchronized (user) {
user.setSomething(something);
}
Added :- It turns out (see here) that this can actually be done like this:
volatile int barrier = 0;
...
user.setSomething(something);
// Forces **all** cached variable to be flushed.
barrier += 1;
marking field as final just means that reference cannot be changed. It means nothing about thread safity of class User. If methods of this class that access fields are synchronized (or use other synchronization technique) it is thread safe. Otherwise it is not.
final only makes the reference not re-assignable, but if the reference points to a mutable class, you can still alter the state inside that object, which causes thead-unsafe.
Your code is only thread safe if the User class is immutable, I.e. all properties of User cannot be altered outside the object, all references in the class point to other immutable class.
If it is not case, then you have to properly synchronize its methods to make it thread safe.
Note that I can't modify the user class and I don't know if it's thread safe itself.
You have to synchronize your access when accessing the User object.
You can for example use the User object to synchronize, so just wrap every access on the user object with something like:
synchronized(user) {
// access some method of the user object
}
That assumes that the user object is only accessed in your threads asynchronously. Also keep the synchronized blocks short.
You could also build a threadsafe wrapper around the user object. I would suggest that if you have a lot of different calls, the code gets cleaner and better to read that way.
good luck!
Concerning threading, finalfields are just guaranteed to be consistent in case of constructor escape, since the JSR-133 about Memory Barrier mechanism:
The values for an object's final fields are set in its constructor.
Assuming the object is constructed "correctly", once an object is
constructed, the values assigned to the final fields in the
constructor will be visible to all other threads without
synchronization. In addition, the visible values for any other object
or array referenced by those final fields will be at least as
up-to-date as the final fields. What does it mean for an object to be
properly constructed? It simply means that no reference to the object
being constructed is allowed to "escape" during construction. (See
Safe Construction Techniques for examples.) In other words, do not
place a reference to the object being constructed anywhere where
another thread might be able to see it; do not assign it to a static
field, do not register it as a listener with any other object, and so
on. These tasks should be done after the constructor completes, not in
the constructor.
However, nothing ensures automatic thread-safety about any final fields in the remaining object's life (meaning after wrapping class's constructor execution).. Indeed, immutability in Java is a pure misnomer:
Now, in common parlance, immutability means "does not change".
Immutability doesn't mean "does not change" in Java. It means "is
transitively reachable from a final field, has not changed since the
final field was set, and a reference to the object containing the
final field did not escape the constructor".
Yes, this is safe. See
Java Language Specification (Java 8) Chapter 17.4.4:
The final action in a thread T1 synchronizes-with any action in another thread T2 that detects that T1 has terminated.
T2 may accomplish this by calling T1.isAlive() or T1.join().
Put this together with 17.4.5. Happens-before Order:
Two actions can be ordered by a happens-before relationship. If one action happens-before another, then the first is visible to and ordered before the second. [..] If an action x synchronizes-with a following action y, then we also have hb(x, y).
So after you call t.join(); in your code you will see the updated changes. Since "the thread that created A instance and called A.aMethod" can impossibly read the value after calling aMethod and before t.join is called (because it is busy with method aMethod), this is safe.
Basically the following works but since I read about the final keyword I am not sure anymore if I have to declare name final if different threads access it?
Thanks in advance.
public class Test4 {
// to ensure thread-safety do we have to declare the variable name final ?
private String name;
public Test4 (String name) {
this.name = name;
}
public void start() {
new MyThread().start();
}
private class MyThread extends Thread {
public void run() {
System.out.println(name);
}
}
public static void main(String[] args) {
Test4 t = new Test4("Don't know if I am threadsafe");
t.start();
}
}
The final modifier - while preventing the member from being re-assigned - does not affect the correctness of the given code1
From the the 17.4.4 Synchronization Order section for the Java 5 Language Specification:
A synchronization order is a total order over all of the synchronization actions of an execution .. Synchronization actions induce the synchronized-with relation on actions, defined as follows:
..
An action that starts a thread synchronizes-with the first action in the thread it starts.
..
Then, since the thread that sets the name member is the one that starts the thread, the synchronization order is guaranteed. (Synchronizes-with implies a Happens-before ordering.)
Note that:
The member name needs only be set before starting the thread: that is, it does not need to be set in the constructor for this synchronizes-with guarantee.
This does not guarantee synchronization ordering - and thus it does not guarantee happens-before or value visibility - between already running threads or threads created elsewhere!
However, final fields do give a much more comfortable feeling (ref. 17.5 Final Field Semantics):
An object is considered to be completely initialized when its constructor finishes. A thread that can only see a reference to an object *after that object has been completely initialized is guaranteed to see the correctly initialized values for that object's final fields.
In this case, with final fields, the value is guaranteed to be visible on every thread after the constructor completes. (This guarantee can be violated by "constructor leaks".)
1 In the supplied code the "non-final" name member is only assigned once before the thread is started.
In different, less trivial, programs other synchronization issues may be exposed. This answer examines if removing final alters the correctness of the supplied code.
All that being said, I consider it "good practice" to use both immutable variables (final) and immutable objects - especially when dealing with threads. Instead of needing to know the little arcane details of the JVM, do the safe proven things and strive for obvious correctness over cleverness or "performance".
See also:
Synchronizing an object shared across threads, but not accessed concurrently
When does java thread cache refresh happens?
Java happend before thread start
final variables are immutable, you can not change the value once it is constructed so it does not have concurrency issue.
You will not get the correct value of the field without final.
Maybe the thread got the old value after you changing the value of field.
Check the Visibility of JMM.
Another link of volatile.
Happends-Before Rule.
Happends-Before in JMM.
Could you be looking for an AtomicReference or perhaps volatile? It depends what you mean by thread safe?
// Atomic to allow deeper control of updates.
private AtomicReference<String> name = new AtomicReference<String>();
// Volatile to ensure it is not cached.
private volatile String vName;
public Test(String name) {
this.name.set(name);
this.vName = name;
}
public void start() {
new MyThread().start();
}
private class MyThread extends Thread {
public void run() {
System.out.println(name.get());
System.out.println(vName);
}
}
final doesn't have nothing with multithreading, but you should put final if your fild shouldn't be changed and is initialized in constructor of class. This means that fild can't be changed latter.
since String is immutable and you declare the field final ,with all threads accessing it after the field assignment, then surely there will be no concurrent issues since the field would be used only for Read operation,in contrast to the case where StringBuilder were used.
Will calling a setter after constructor execution but before returning the reference will be a safe publication ?
public class SafePublication {
private int i = 0;
private SafePublication() {
i = 10;
}
// Here we are calling setter are object creation.
//Will this change be visible to other threads
public static SafePublication getInstance() {
SafePublication pub = new SafePublication();
pub.setVal(20);
return pub;
}
private void setVal(int x) {
this.i = x;
}
}
No it won't be safe.
The setVal method is not synchronized, and i is not volatile. Therefore, there will be no synchronization point between an update to i (via setVal) and any code run on another thread that reads i. The fact that the setVal call happens in the thread that constructs the instance makes on difference.
The bottom line is that another thread may see the value of i as any one of 0, 10 or 20.
How may another thread see that value if the reference to the object has not been returned yet?
It is not. The problem is that the other thread may not see the correct value of i.
I think you are confusing this situation with the case where the field is final. There, the JLS does specify that the field is safely published. The problem is that this guarantee does not apply to non-final fields; see JLS 17.5. The wording is as follows:
"An object is considered to be completely initialized when its constructor finishes. A thread that can only see a reference to an object after that object has been completely initialized is guaranteed to see the correctly initialized values for that object's final fields. "
(Emphasis added)
i would rather say another thread may see the value of i as any one of 10 or 20. It is guaranteed not to see 0.
AFAIK, there is nothing in JLS 17.4 or JLS 17.5 that offers that guarantee. The only thing that is guaranteed is that nothing will see the value of i before default initialization has taken place. (Please feel free to prove me wrong ... with references to the JLS.)