For the following simplified class:
public class MutableInteger {
private int value;
public MutableInteger(int initial) {
synchronized(this) { // is this necessary for memory visibility?
this.value = initial;
}
}
public synchronized int get() {
return this.value;
}
public synchronized void increment() {
this.value++;
}
...
}
I guess the general question is for mutable variables guarded by synchronization is it necessary to synchronize when setting the initial value in the constructor?
You're right, without the synchronized block in the constructor there is no visibility guarantee for non-final fields, as can be seen in this example.
However in practice I would rather use volatile fields or the Atomic* classes in situations like this.
Update: It is also important to mention here that in order for your program to be correctly synchronized (as defined by the JLS), you will need to publish the reference to your object in a safe manner. The cited example doesn't do that, hence why you may see the wrong value in non-final fields. But if you publish the object reference correctly (i.e. by assigning it to a final field of another object, or by creating it before calling Thread.start()), it is guaranteed that your object will be seen at least as up-to-date as the time of publishing, therefore making the synchronized block in the constructor unnecessary.
Though you've accepted an answer, let me add my two cents.
Based on what I've read, synchronization or making the field volatile would not grantee the following visibility.
A thread T1 may see a not-null value for this, but unless you've made the field value final, there's a good chance of thread T1 seeing the default value of value.
The value could be a volatile or been accessed within synchronized blocks (monitor acquire and release), either way provided that the correct execution order was followed, there's happens-before edge from the write to the read of value. There's no argument on that.
But it's not the happens before edge that we have to consider here, but the correct publication of the object itself(MutableInteger).
Creating an object is twofold where the JVM first allocates a heap space and then start initializing fields. A thread may see a not-null reference of an object but an uninitialized field of that as long as the said field is not final (Assuming reference has been correctly published).
Related
this class can be used in multi thread because it is thread-safe.
public class Hello {
private int value = 0;
public synchronized int get() {
return value;
}
public synchronized void set(int value) {
this.value = value;
}
}
i know that the reason that we must use synchronized when get() ,besides set() is memory visibility.
and java volatile keyword can be used for memory visibility.
so then.. this class is also thread-safe??
public class Hello {
private volatile int value = 0;
public int get() {
return value;
}
public synchronized void set(int value) {
this.value = value;
}
}
In your specific example, you don't need that extra synchronized. Given that you have already mentioned memory visibility (aka happens-before), I won't go deeper to explain this.
However, it does not apply generally. There are several assumptions in your example making it enough to simply use volatile
Type of value
Although you are simply doing a simple retrieval/assignment of value, it is not always guaranteed to be atomic for all data type. Iirc, Java only guarantee that such operation is atomic for int and types smaller that int. Which means, for example, if value is of type long, even you have declared it with volatile, you may still corrupt value with your above example
Operations on value
Ok, let's assume it is an int. In your example, you are simply getting and assigning an int for which the operation is atomic, hence simply using volatile is enough. However if you have another method doing something like value++, using volatile is not sufficient. In such case, you may either consider using Atomic* or use synchronized
Update: I later found that JLS https://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.7 mentioned that using volatile would enforce atomic read/write on double/long. So my original point 1 was actually wrong
In your example, there's no need to use synchronized in neither the get() nor the set method, given the value attribute is declared with the volatile keyword.
This is because the volatile keyword forces a happens-before relation between writer and reader threads.
Java Language Specification, Section 8.3.1.4. volatile fields:
The Java programming language allows threads to access shared variables (§17.1). As a rule, to ensure that shared variables are consistently and reliably updated, a thread should ensure that it has exclusive use of such variables by obtaining a lock that, conventionally, enforces mutual exclusion for those shared variables.
The Java programming language provides a second mechanism, volatile fields, that is more convenient than locking for some purposes.
A field may be declared volatile, in which case the Java Memory Model ensures that all threads see a consistent value for the variable (§17.4).
So, in your case, there's no need to synchronize the get() and set() methods.
In your class Hello there is only one field int value. Synchronized locks whole object and thus heavy operation, Instead you can use AtomicInteger. Since Atomic* variables are faster. Volatile just satisfies "happens before" you cannot achieve atomicity for operations like "check then act" with volatiles.
To make Hello class thread-safe, the best way
import java.util.concurrent.atomic.AtomicInteger;
public class Hello {
private AtomicInteger value;
public int get() {
return this.value.get();
}
public synchronized void set(int value) {
this.value.set(value);
}
}
As mentioned in this post
If some object has only one field or its critical updates are
limited to only one field of object so instead of using
synchronization or other thread safe collections , Atomic variables
(AtlomicInteger, AtomicReference etc.) can be utilized.
As I understand it, volatile helps in memory visibility and synchronized helps in achieving execution control. Volatile just guarantees that the value read by the thread would have the latest value written to it.
Consider the following:
public class Singleton{
private static volatile Singleton INSTANCE = null;
private Singleton(){}
public static Singleton getInstance(){
if(INSTANCE==null){
synchronized(Integer.class){
if(INSTANCE==null){
INSTANCE = new Singleton();
}
}
}
return INSTANCE;
}
}
In the above piece of code, we use double-checked locking. This helps us create only one instance of Singleton and this is communicated to the other threads by the creating thread as soon as possible. This is what the keyword volatile does. We need the above synchronized block because the delay in the thread reading the INSTANCE variable as null and initializing the object could cause a race condition.
Now consider the following:
public class Singleton{
private static Singleton INSTANCE = null;
private Singleton(){}
public static synchronized Singleton getInstance(){
if(INSTANCE==null){
INSTANCE = new Singleton();
}
return INSTANCE;
}
}
Say we have 2 threads t1 and t2 trying to get the Singleton object. Thread t1 enters the getInstance() method first and creates the INSTANCE object. Now this newly created object should be visible to all the other threads. If the INSTANCE variable is not volatile then how do we make sure that the object is still not in t1's memory and visible to other threads. How soon is the above INSTANCE initialized by t1 visible to other threads ?
Does this mean that it is advisable to always make variables volatile with synchronized ?
In what scenarios would we not require the variable to be volatile ?
P.S I have read other questions on StackOverflow but could not find the answer to my question. Please comment before down-voting.
My question arises from the explanation given here
I think what you're missing is this from JLS 17.4.4:
An unlock action on monitor m synchronizes-with all subsequent lock actions on m (where "subsequent" is defined according to the synchronization order).
Which is very similar to the bullet about volatile variables:
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).
Then in 17.4.5:
If an action x synchronizes-with a following action y, then we also have hb(x, y).
... where hb is the "happens-before" relation.
Then:
If one action happens-before another, then the first is visible to and ordered before the second.
The memory model is incredibly complicated and I don't claim to be an expert, but my understanding is that the implication of the quoted parts is that the second pattern you've shown is safe without the variable being volatile - and indeed any variable which is only modified and read within synchronization blocks for the same monitor is safe without being volatile. The more interesting aspect (to me) is what happens to the variables within the object that the variable's value refers to. If Singleton isn't immutable, you've still potentially got problems there - but that's one step removed.
To put it more concretely, if two threads call getInstance() when INSTANCE is null, one of those threads will lock the monitor first. The write action of a non-null reference to INSTANCE happens-before the unlock operation, and that unlock operation happens-before the lock operation of the other thread. The lock operation happens-before the read of the INSTANCE variable, therefore the write happens-before the read... at which point, we are guaranteed that the write is visible to the reading thread.
This explanation of what is happening here is entirely wrong, as I misunderstood the Java Memory Model. See Jon Skeet's answer.
Safe lazy initialization
The action you are attempting in this case is "lazy-initialization", and that particular pattern is useful for instances, but sub-optimal for static variables. For static variables, the lazy initialization holder class idiom is preferred.
The following quote and code block are copied directly from Item 71 of Effective Java (2nd Edition), by Josh Bloch:
Because there is no locking if the field is already initialized, it
is critical that the field be declared volatile.
// Double-check idiom for lazy initialization of instance fields
private volatile FieldType field;
FieldType getField() {
FieldType result = field;
if (result == null) { // First check (no locking)
synchronized(this) {
result = field;
if (result == null) // Second check (with locking)
field = result = computeFieldValue();
}
}
return result;
}
In one of his talks, he recommended to copy this structure exactly when performing lazy initialization for instance fields, as it is optimal in such situations, and it is very easy to break it by changing it.
What is actually happening?
EDIT: This section is incorrect.
The volatile keyword means that all read and write operations for the variable are atomic; that is, they happen as one single step from the perspective of anything else. Additionally, volatile variables are always read from and written to main memory, not processor cache. The combination of these two properties guarantees that, as soon as a volatile variable variable is modified on one thread, subsequent reads on another thread will read the updated value. This guarantee is not present for non-volatile variables.
The double-check idiom does not guarantee that only one instance is created. Rather, it is so that, once the variable is initialized, future calls to getInstance() do not need to enter a synchronized block, which is expensive.
The guarantee that it is not initialized twice is made by the fact that (a) it is a volatile field, and (b) it is checked (again) inside of the synchronized block. The outer check helps efficiency; the inner check guarantees single initialization.
I highly recommend reading Item 71 of Effective Java (2nd Edition) for a more complete explanation. I also recommend the book in general as being fantastic.
UPDATE:
The local result variable used reduces the number of accesses of the volatile field needed, which improves performance. If the local variable was left out, and all reads and writes directly accessed the volatile field, it should have the same result, but take slightly longer.
Are multiple threads guaranteed to see the same version of a shared object to which they have a reference? Here is a code sample:
public static void main(String[] args) {
final AtomicBoolean flag = new AtomicBoolean(false);
new Thread(){
public void run() { possibly read and mutate flag }
}.start();
new Thread(){
public void run() { possibly read and mutate flag }
}.start();
while (!flag.get()) {
Thread.yield();
}
}
To be clear, I am wondering whether writes by the child threads to the shared object are seen by the parent and sibling threads.
Are multiple threads guaranteed to see the same version of a shared local variable in their scope.
In general, it depends on what you mean by "the same version". It also depends on the nature of the variable (e.g. how it is declared and initialized) ... and on how the threads use it.
(In general, Java doesn't do "versions" of variables. A thread accessing a shared variable or object will either see the latest state, or it won't. If it sees a state that isn't the latest state, then there are no guarantees as to what it will see. In particular, it may see something that doesn't directly correspond to any notional version of the object ... due to word-tearing and other cache-related memory artefacts.)
In your example you are using a final local variable within an inner class (in this case you have two anonymous inner classes). When you do that, the compiler creates a corresponding synthetic variable in the inner class that is initialized with the value of the variable in the method scope. The compiled inner class then refers to the value of the synthetic variable instead of the original variable.
In your example, it is guaranteed that the inner classes (e.g. your threads) will see the same (reference) value as in the original variable. Furthermore, it is guaranteed that they will (at least initially) see a consistent snapshot of whatever object it is that it references. (And since it is an AtomicXxxx class, it will always be consistent for all threads that can access it. Guaranteed.)
OK, so what about other cases:
If flag was a static or instance field that was also final, then we wouldn't have synthetic variables, and each nested class would be referencing the same shared variable. But it would all still work.
If flag was a static or instance field and it wasn't final, but nothing changed the field (after creating of the threads) then it would still be OK. (Though you could argue that this is fragile ... because something could change the field.)
If flag was a static or instance field and it wasn't final or volatile, then the threads would initially see the same state as the parent thread. But if either the original thread or any of the other threads changed the variable (etcetera), then the others are not guaranteed to see the new state ... unless they respective threads synchronize properly.
I would like to know if changes to flag made in one thread are seen immediately by the other two threads.
As I said above, it depends ...
In your example, the answer is "yes", because you use a final reference to AtomicBoolean.
If you had declared flag as a boolean and marked it as volatile, then the answer would be "yes".
If you had declared flag as a boolean and non-volatile, then the answer would be "no".
If flag was a final reference to an ordinary object with a mutable non-volatile boolean field, then the answer would also be "no". (The threads would all see the same object, but they wouldn't consistently see the latest state. The solution would be to use synchronized getters and setters, or equivalent.)
Yes, the two threads share the same final AtomicBoolean which is a class used to set the truth value. The variable flag itself can't be recreated because it is final. But you can perform actions on it to set value. Just like a final int[] can't be assigned to different size but you can change the value of what's inside.
final AtomicBoolean flag = new AtomicBoolean(false);
new Thread(){
public void run(){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
flag.set(true);
}
}.start();
new Thread(){
public void run(){
flag.set(false);
}
}.start();
Thread.sleep(200);// comment this line, you see different results
System.out.println(flag);
In this case, yes. The Java Language Specification says that calling Thread.start() synchronizes-with all previous actions on the calling thread:
An action that starts a thread synchronizes-with the first action in the thread it starts.
This creates a happens-before relationship between all writes on your main thread (including any writes the constructor of the AtomicBoolean made to initialize itself) are made visible to the thread your main thread started.
A call to start() on a thread happens-before any actions in the started thread.
So basically you are good to go. Your AtomicBoolean object is visible to both threads, and they both see the same object.
This pattern is called Safe Publication, btw. You use it to safely publish an object you create (like your AtomicBoolean) so that other threads can see it. (And yes, Thread.start() isn't on the list there of ways to safely publish an object because Thread.start() isn't general enough. But it's the same idea, and works the same way.)
The local variable is not shared1, and being final means that there would be no worry of it changing even if it was the case. (A question about member variables would result in a different response although, excluding constructor leakage, a final member would provide the same guarantees.)
The same object is shared across threads; it will be the same object and will adhere to the defined AtomicBoolean contract.
A boolean value that may be updated atomically. See the java.util.concurrent.atomic package specification for description of the properties of atomic variables.
In short the package documentation specifies the following which in turn guarantees happens-before relationships.
get has the memory effects of reading a volatile variable.
set has the memory effects of writing (assigning) a volatile variable.
There are many questions relating to the thread-safey of volatile (and AtomicXYZ objects), eg. see Is a volatile int in Java thread-safe? and Is AtomicBoolean needed to create a cancellable thread?
1 Anonymous types, including Java 8 lambdas, do not create closures/lexical bindings to variables in scope and as such are not capable of sharing local variables; rather variables are synthesized with the value of the final (or effectively final) variable from the enclosing scope which is bound when the anonymous type is instantiated.
Consider the following class:
public class MyClass
{
private MyObject obj;
public MyClass()
{
obj = new MyObject();
}
public void methodCalledByOtherThreads()
{
obj.doStuff();
}
}
Since obj was created on one thread and accessed from another, could obj be null when methodCalledByOtherThread is called? If so, would declaring obj as volatile be the best way to fix this issue? Would declaring obj as final make any difference?
Edit:
For clarity, I think my main question is:
Can other threads see that obj has been initialized by some main thread or could obj be stale (null)?
For the methodCalledByOtherThreads to be called by another thread and cause problems, that thread would have to get a reference to a MyClass object whose obj field is not initialized, ie. where the constructor has not yet returned.
This would be possible if you leaked the this reference from the constructor. For example
public MyClass()
{
SomeClass.leak(this);
obj = new MyObject();
}
If the SomeClass.leak() method starts a separate thread that calls methodCalledByOtherThreads() on the this reference, then you would have problems, but this is true regardless of the volatile.
Since you don't have what I'm describing above, your code is fine.
It depends on whether the reference is published "unsafely". A reference is "published" by being written to a shared variable; another thread reads the variable to get the reference. If there is no relationship of happens-before(write, read), the publication is called unsafe. An example of unsafe publication is through a non-volatile static field.
#chrylis 's interpretation of "unsafe publication" is not accurate. Leaking this before constructor exit is orthogonal to the concept of unsafe publication.
Through unsafe publication, another thread may observe the object in an uncertain state (hence the name); in your case, field obj may appear to be null to another thread. Unless, obj is final, then it cannot appear to be null even if the host object is published unsafely.
This is all too technical and it requires further readings to understand. The good news is, you don't need to master "unsafe publication", because it is a discouraged practice anyway. The best practice is simply: never do unsafe publication; i.e. never do data race; i.e. always read/write shared data through proper synchronization, by using synchronized, volatile or java.util.concurrent.
If we always avoid unsafe publication, do we still need final fields? The answer is no. Then why are some objects (e.g. String) designed to be "thread safe immutable" by using final fields? Because it's assumed that they can be used in malicious code that tries to create uncertain state through deliberate unsafe publication. I think this is an overblown concern. It doesn't make much sense in server environments - if an application embeds malicious code, the server is compromised, period. It probably makes a bit of sense in Applet environment where JVM runs untrusted codes from unknown sources - even then, this is an improbable attack vector; there's no precedence of this kind of attack; there are a lot of other more easily exploitable security holes, apparently.
This code is fine because the reference to the instance of MyClass can't be visible to any other threads before the constructor returns.
Specifically, the happens-before relation requires that the visible effects of actions occur in the same order as they're listed in the program code, so that in the thread where the MyClass is constructed, obj must be definitely assigned before the constructor returns, and the instantiating thread goes directly from the state of not having a reference to the MyClass object to having a reference to a fully-constructed MyClass object.
That thread can then pass a reference to that object to another thread, but all of the construction will have transitively happened-before the second thread can call any methods on it. This might happen through the constructing thread's launching the second thread, a synchronized method, a volatile field, or the other concurrency mechanisms, but all of them will ensure that all of the actions that took place in the instantiating thread are finished before the memory barrier is passed.
Note that if a reference to this gets passed out of the class inside the constructor somewhere, that reference might go floating around and get used before the constructor is finished. That's what's known as unsafe publishing of the object, but code such as yours that doesn't call non-final methods from the constructor (or directly pass out references to this) is fine.
Your other thread could see a null object. A volatile object could possibly help, but an explicit lock mechanism (or a Builder) would likely be a better solution.
Have a look at Java Concurrency in Practice - Sample 14.12
This class (if taken as is) is NOT thread safe. In two words: there is reordering of instructions in java (Instruction reordering & happens-before relationship in java) and when in your code you're instantiating MyClass, under some circumstances you may get following set of instructions:
Allocate memory for new instance of MyClass;
Return link to this block of memory;
Link to this not fully initialized MyClass is available for other threads, they can call "methodCalledByOtherThreads()" and get NullPointerException;
Initialize internals of MyClass.
In order to prevent this and make your MyClass really thread safe - you either have to add "final" or "volatile" to the "obj" field. In this case Java's memory model (starting from Java 5 on) will guarantee that during initialization of MyClass, reference to alocated for it block of memory will be returned only when all internals are initialized.
For more details I would strictly recommend you to read nice book "Java Concurrency in Practice". Exactly your case is described on the pages 50-51 (section 3.5.1). I would even say - you just can write correct multithreaded code without reading that book! :)
The originally picked answer by #Sotirios Delimanolis is wrong. #ZhongYu 's answer is correct.
There is the visibility issue of the concern here. So if MyClass is published unsafely, anything could happen.
Someone in the comment asked for evidence - one can check Listing 3.15 in the book Java Concurrency in Practice:
public class Holder {
private int n;
// Initialize in thread A
public Holder(int n) { this.n = n; }
// Called in thread B
public void assertSanity() {
if (n != n) throw new AssertionError("This statement is false.");
}
}
Someone comes up an example to verify this piece of code:
coding a proof for potential concurrency issue
As to the specific example of this post:
public class MyClass{
private MyObject obj;
// Initialize in thread A
public MyClass(){
obj = new MyObject();
}
// Called in thread B
public void methodCalledByOtherThreads(){
obj.doStuff();
}
}
If MyClass is initialized in Thread A, there is no guarantee that thread B will see this initialization (because the change might stay in the cache of the CPU that Thread A runs on and has not propagated into main memory).
Just as #ZhongYu has pointed out, because the write and read happens at 2 independent threads, so there is no happens-before(write, read) relation.
To fix this, as the original author has mentioned, we can declare private MyObject obj as volatile, which will ensure that the reference itself will be visible to other threads in timely manner
(https://www.logicbig.com/tutorials/core-java-tutorial/java-multi-threading/volatile-ref-object.html) .
If multiple threads read a primitive type that has been previously set and does not change ever after, can they get a wrong value?
For example, assume the following simple code excerpt:
public static final boolean proceed = read(); // Read the value from a file
public static void doSomething() // Method accessed by multiple threads
{
if (proceed)
{
System.out.println("TRUE");
}
else
{
System.out.println("FALSE");
}
}
Assuming that the proceed variable is initialized to true, is it possible that, in one or more of the multiple threads that simultaneously run the doSomething() method, the printed message is FALSE?
If the proceed variable was mutable, surely that would be possible, hence the need for synchronization, or for using an AtomicBoolean (e.g., as per this question). But in this case proceed is immutable and only set once, during the static initialization of the containing class.
Similarly for other primitive types, if a value is set as final, it should always be thread-safe to access it afterwards, correct?
The fact that your variable is final guarantees that all threads will see it in a consistent post-initialisation state. This is applicable to objects' references too (i.e. all threads will see a non null value of the Object if it has been initialised to a non null reference - but if your object is not thread-safe, some threads might see the object itself in an inconsistent or stale state).
ps: that is assuming your read method does not try to read the boolean value in which case it would see the default (false) value.
You are saying it is immutable (static and final), so we can safely say it is thread-safe.
The reference is thread-safe because it's immutable.
If it were mutable, you would need to use the volatile keyword to make sure you get the latest value if modified in another thread.
Do you ever use the volatile keyword in Java?
Since proceed is static and final , it can not be reassigned which turns in to thread-safe.
static says it is class level and final says it's value can't be changed and this is a primitive so defiantly this immutable and hence thread-safe .