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 .
Related
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).
I have an android Application object (although this is purely a java question I believe) as below
I wanted to understand if the way I have used volatile is correct, I have defined appData in Application as volatile, does that automatically guarantee that all the variables inside AppData object (each of them are complex objects like arrays , etc themselves) are also volatile or do I need to explicitly make them volatile like i have done
Morever, as I mention in the comment tagged QUESTION, does equating a new variable X to a volatile variable also make X volatile?
public class App extends Application{
private volatile static AppData appData;
public void fetchMePageInfo(long idOfUserIfNotForSelf) {
RestService.getMePageInfo(new Callback<MePageInfo>() { // RestService is just another class that calls Web server, and has static method getMepageInfo
#Override
public void success(MePageInfo newMePageInfo, Response response) {
// for successful server request, store the newly fetched me page in array
// and set ref to both self me page ref = me page to be displayed = new object,
ArrayList<MePageInfo> mPageInfoList = appData.getMePageInfoList();
// QUESTION : AppData is volatile, but does that mean mPageInfoList is also threadsafe?
MePageInfo selfRef = appData.getUserMePageInfo();
if (selfRef != null) {
// if me page exists already, additionally remove the existing me page first
mPageInfoList.remove(selfRef);
}
mPageInfoList.add(newMePageInfo);
appData.setUserMePageInfo(newMePageInfo); // does not automatically call change listeners
}
});
}
}
public class AppData {
/**
this has the MePageInfo objects of the various other users that the logged in user might go to
for quick fetch, instead of calling server each time
**/
volatile ArrayList<MePageInfo> mePageInfoList = new ArrayList<MePageInfo>();
// region self Me page info data
/**
* the MePageInfo for the logged in user, this is null initially and is filled by FetchGenericMePageInfo for the user
*/
volatile MePageInfo userMePageInfo = null;
}
Volatile and thread-safe are not the same thing. volatile guarantees you that
A write to a volatile variable and a subsequent read of this variable establishes a happens-before relationship between two threads.
All read and writes of this particular variable are atomic.
That's all what it does. So if you assign a value of a volatile variable to another one, it does not make it volatile. The concept of thread safety is more complex and the fact that a variable is volatile does not mean that even this variable itself is thread-safe.
Being "volatile" is a property of a variable, not a property of the object that it refers to. So (assuming we're talking about reference variables here, not primitives), marking a variable "volatile" does not make an object thread-safe. And it's possible that you'll have a volatile variable and a non-volatile variable that both refer to the same object.
So when you mark a reference variable as "volatile", you're saying that other threads may make the variable refer to a different object. You're not saying that other threads may mutate the object that it refers to.
So to answer your first question, the volatility of fields within an object is completely independent of the volatility of any variable that refers to the object. And to answer your second question, a variable can't somehow become volatile by referring to a volatile object.
does that automatically guarantee that all the variables inside AppData object (each of them are complex objects like arrays , etc themselves)
No. Doing something like:
appData = new AppData();
appData.mePageInfoList = new ArrayList<>();
Is not thread-safe. The write to mePageInfoList can be read out of order. So to answer your question, there is no garuantee about when the write to the fields inside AppData will be read.
do I need to explicitly make them volatile like i have done
Yes, but even then you're not necessarily safe. For instance ArrayList isn't thread-safe, so assigning to mePageInfoList will be thread-safe but any later mutation of the collection will be at risk.
does equating a new variable X to a volatile variable also make X volatile?
Not exactly sure what you are asking, can you give an example?
At the about bottom of http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html, it says:
Double-Checked Locking Immutable Objects
If Helper is an immutable object, such that all of the fields of Helper are final, then double-checked locking will work without having to use volatile fields. The idea is that a reference to an immutable object (such as a String or an Integer) should behave in much the same way as an int or float; reading and writing references to immutable objects are atomic.
The sample and explanation of mutable one is as follows:
// Broken multithreaded version
// "Double-Checked Locking" idiom
class Foo {
private Helper helper = null;
public Helper getHelper() {
if (helper == null)
synchronized(this) {
if (helper == null)
helper = new Helper();
}
return helper;
}
// other functions and members...
}
The first reason it doesn't work
The most obvious reason it doesn't work it that the writes that initialize the Helper object and the write to the helper field can be done or perceived out of order. Thus, a thread which invokes getHelper() could see a non-null reference to a helper object, but see the default values for fields of the helper object, rather than the values set in the constructor.
If the compiler inlines the call to the constructor, then the writes that initialize the object and the write to the helper field can be freely reordered if the compiler can prove that the constructor cannot throw an exception or perform synchronization.
Even if the compiler does not reorder those writes, on a multiprocessor the processor or the memory system may reorder those writes, as perceived by a thread running on another processor.
My question is: why immutable class does't have the problem? I cannot see any relation of the reorder with whether the class is mutable.
Thanks
The reason why the code is "broken" for usual objects is that helper could be non null but point to an object that has not been completely initialised yet as explained in your quote.
However if the Helper class is immutable, meaning that all its fields are final, the Java Memory Model guarantees that they are safely published even if the object is made available through a data race (which is the case in your example):
final fields also allow programmers to implement thread-safe immutable objects without synchronization. A thread-safe immutable object is seen as immutable by all threads, even if a data race is used to pass references to the immutable object between threads. This can provide safety guarantees against misuse of an immutable class by incorrect or malicious code. final fields must be used correctly to provide a guarantee of immutability.
Immutable classes did have the problem. The part that you have quoted is true after changes to the Java Memory were made in JSR133.
Specifically the changes that affect immutable objects are related to some changes that were made to the final keyword. Checkout http://www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html#finalRight.
The important part is:
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.
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.
Strategy for defining immutable class says that
all the fields should be final.
For ex:
private String name;
Why does it have to be final?
Since I am not giving setter methods for it? It can't be changed.
Thanks.
If you read
private final String name;
you know the field is immutable.
If you read
private String name;
you have to read the entire class to check it is not changed anywhere. This is means much more work for you.
You may remember now, having just written the class that you didn't add a setter, but after writing many more classes you read your own class six month later, you won't remember reliably.
Even if it is not changed now, someone (possibly yourself) could change it later by adding code. However, you might have made the assumption the value won't change.
In short, only make it non-final when you mean the value to change, and make it final when you didn't expect it to change. Don't leave it as a may be/may be not.
Now imagine you are used to being clear about which fields can be changed and which cannot. This saves you a lot of work when reading some else's code. But you discover that you are reading code which is not clear and non-final doesn't mean it was changed, it now means you have to check things, you wouldn't normally have to check which is one more headache in trying to understand some code you really don't need.
A simple example of how much harder it is to read code to determine if a field is effectively final.
public class A {
static class B {
private int x;
}
// some code
This all looks fine up to this point, no setters or even methods in B. So B.x is immutable right?
static class C {
public void update(B b, int x) {
b.x = x; // this really compiles
}
}
}
Oops no, you have to read the whole class file.
It is far better for you to make every field you can final (which should have been the default IMHO) when you write the code, rather than leaving it for someone to figure out later.
The main reason (IMHO) is that when field is final is guaranteed to be visible in other threads immediately after constructor is finished.
Keeping the field final emphasizes the fact that it cannot be changed anywhere else.
Self documenting code the the field should not be changed
Compiler will help you by giving error if you change the field somewhere else
So final helps in many ways for making object Immutable.
It's good practice to make immutable fields final, even on otherwise mutable objects.
Note that private fields of one object in fact CAN be accessed by other instances of the same class.
An object (class or instance) is immutable, if its internal state cannot be changed (reflection doesn't count).
Making a field final guarantees only that the value (if it's a primitive) or reference (for non-primitives) cannot be changed.
For non-primitives, this doesn't automatically mean that the referenced value is also immutable. Which means that if your final field references, for example, a list, one cannot exchange the list, but add/remove values from it, thus changing the state of the object.
For an object to be immutable:
The internal state must be determined upon construction and can never change
This means all fields that define the state must be final (you may have other helper fields which don't belong to the state, that's ok but rare).
This also means that all refernced objects must be immutable. Some objects such as String are already immutable, others such as collections can be wrapped to make them immutable (Collections.immutableList|Set|Collection|...)
Making primitive types final ensures immutability. However making non primitive objects final sometimes makes no sense since final object states can be mutated.As Greg points out this depends on the type of Object in question
As the example you showed, all properties are primitive hence final keword make sense.
One benifit of declaring a field final is that it allows compiler to detect attempts to change the field during refactoring. A class can be immutable even if its fields are not final.
JVM guarantees that final fields of a class will be initialized before any thread gets hold of the object. Without this guarantee, a reference to an object may be published, i.e. become visible, to another thread before all the fields of this object are initialized, due to reorderings or other optimizations. This could cause racy access to these fields.
This is why, when creating an immutable object, you should always make all its fields final, even if they are not accessible via getter methods.