I have a non-atomic java property, which can be set by synchronized setter. My question is, can I read this property by non-synchronized getter? Thanks.
You can read the property, i.e. the thread will see some value but the problem is that it is not predictable -- it may not reflect the most recent value written by another thread or it may even be a random value. Therefore, you should synchronize the getter as well. It is not safe to only synchronize methods that write to a variable.
If the property is not atomic, you might have to introduce a ReadwriteLock.
See http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/ReadWriteLock.html
The answer depends on whether the field is volatile.
If the field is not volatile, then the other answers are correct. You can read the value, but the thread doing the read many not be able "see" the value that another thread wrote. The value written might be in a thread-local cache, so the second thread might always see the old value. In addition, the JIT compiler is free to reorder the code in a way that only works if no one is reading the value concurrently.
If the field is volatile, then you will get the behavior you want. The JVM will ensure that every thread will get the latest value.
Note you shouldn't do read-modify-write operations (like incrementing an integer field) on a volatile field outside of a synchronized block, because race conditions can result in unexpected results.
For more details, read Java Concurrency in Practice.
You can read the value through getter method but you can get unpredictable value.
Because the movement you are getting value from getter it might be possible that other thread call setter method and change the value. So to avoid data violation we should make setter and getter both synchronize and it must be lock under same object lock.
Related
I have two threads sharing the same variable of type boolean. I discovered that I have to use volatile to guarantee the value is always read from main memory. But now I want to get rid of this volatile identifier, how can I achieve that? Is it true that I easily can extract my boolean property into an object. As the reference to object never change the thread will always access the correct value from the main memory. Will this work?
I have to use volatile to guarantee the value is always read from
main memory
That is not how volatile work. volatile is used to build a happens-before relation ship:
This means that changes to a volatile variable are always visible to
other threads. What's more, it also means that when a thread reads a
volatile variable, it sees not just the latest change to the volatile,
but also the side effects of the code that led up the change.
—— From the doc.
But now I want to get rid of this volatile identifier, how can I
achieve that?
Like said in another answer, you can use AtomicBoolean. Or, add synchronized block around the code reading/writing this variable. Or use some other mechanism, as well as they can build a happens-before relation ship between reading and writing this varibale in different threads.
Is it true that I easily can extract my boolean property into an
object. As the reference to object never change the thread will always
access the correct value from the main memory. Will this work?
No. The reference do not change, this does not mean the fresh object is always visible to other reading threads after it is updated.
you can also use AtomicBoolean instead if you do not like the keyword - also this will allow write access to be thread safe too
Is it safe to say that a ThreadLocal variable is conceptually the 'opposite' of a volatile variable in Java?
Because in the former, every thread will only read/updatea local copy of the variable. But in the latter, every thread will always see the latest value of the variable that is in main memory....no chance of seeing stale values.
Exactly but with a slight twist,
a ThreadLocal variable is a variable different for each thread
any other variable exists only once so common for each Thread using the same object, whether it is volatile or not.
Volatile however specifies some kind of thread read/write boundary so they must synchronize on the latest value written by any other thread. However using volatile does not ensure thread safety.
E.g. a increment method incrementing a volatile int might still generate duplicates. To be sure that works thread safe you must synchronize the method updating the volatile attributes!
check this for more detailed information: https://www.cs.umd.edu/users/pugh/java/memoryModel/jsr-133-faq.html
Say that I have a private variable and I have a setVariable() method for it which is synchronized, isn't it exactly the same as using volatile modifier?
No. Volatile means the variable isn't cached in any per-thread cache, and its value is always retrieved from main memory when needed. Synchronization means that those per-thread caches will be kept in sync at certain points. In theory, using a volatile variable can come with a great speed penalty if many threads need to read the value of the variable, but it is changed only rarely.
No, calling a synchronized getXXX/setXXX method is not the same as reading/writing to a volatile variable.
Multiple threads can concurrently read from or write to a volatile variable. But only one thread at a time can read from or write to a variable that is guarded by a synchronized block.
volatile variables are not synchronized (at least, not in the way synchronized stuff is synchronized). What volatile does is ensure that a variable is retrieved each time it's used (ie: it prevents certain kinds of optimization), and IIRC that it's read and written in the correct order. This could conceivably emulate some kinds of synchronization, but it can't work the same if your setter has to set more than one thing. (If you set two volatile variables, for example, there will be a point where one is set and the other isn't.)
Actually No.
volatile is actually weaker form of synchronization, when field is declared as a volatile the compiler and runtime understands that this variable is shared and operations on it shouldn't be reordered with other memory operations. Volatile variable aren't cached in registers or in caches where they are hidden from other processors, so a read of a volatile variable always return a recent write by any thread.
just an example :
First thread run :
while(stopped){
... do something
}
Second thread run :
stopped = true;
it's useful to declare stopped as a volatile boolean for the first thread to have a fresh value of it.
There is no any relation.
Basically
Volatile => it always retrieves parameter's latest value
Synchronized => it serves only 1 thread at the same time
This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Thread safety in Java class
I'm reading Java concurrency in Practice, and I've come to an example that puzzles me.
The authors state that this class is not threadsafe
public class MutableInteger {
private int number;
public int getInt() {
return number;
}
public void setInt(int val) {
number = val;
}
}
And they also state that synchronizing only one method (the setter for example) would not do; you have to syncronize both.
My question is: Why? Wouldn't synchronizing the setter just do?
Java has a happens before/happens after memory model. There needs to be some common concurrent construct (e.g. synchronized block/method, lock, volatile, atomic) on both the write path and the read path to trigger this behaviour.
If you synchronize both methods you are creating a lock on the whole object that will be shared by both the read and write threads. The JVM will ensure that any changes that occur on the writing thread that occur before leaving the (synchronized) setInt method will be visible to any reading threads after they enter the (synchronized) getInt method. The JVM will insert the necessary memory barriers to ensure that this will happen.
If only the write method is synchronized then changes to the object may not be visible to any reading thread. This is because there is no point on the read path that the JVM can use to ensure that the reading thread's visible memory (cache's etc.) are in line with the writing thread. Make the getInt method synchronized would provide that.
Note: specifically in this case making the field 'number' volatile would give the correct behaviour as volatile read/write also provides the same memory visibility behaviour in the JVM and the action inside of the setInt method is only an assignment.
It's explained in the book before the sample (page 35):
"Synchronizing only the setter would not be sufficient: threads calling get would still be able to see stale values."
Stale data: When the reader thread examines ready, it may see an out-of-date value. Unless synchronization is used every time a variable is accessed, it is possible to see a stale value for that variable. Worse, staleness is not all-or-nothing: a thread can see an up-to-date value of one variable but a stale value of another variable that was written first.
If you only Synchronize the setter method, you could only guarantee the attribute would not be amended incorrectly, but you could not be sure it is stale value when you try to read the variable.
because number is not volatile, and getInt() is not synchronized, getInt() may return stale values. For more information, read about the java memory model.
This may seem a very silly question.
Consider this:
I have a simple Boolean object with a getter and a setter. Now both of the methods are called from a lot of threads very frequently.
Do I need to have a synchronization for this boolean?
Also are Boolean assignments atomic operations?
[UPDATE]:
I know about Atomic Boolean already. I already have a lot of varied solutions, But I was specifically looking for answers and justification of answers for the above 2 question.
No, Boolean access is NOT atomic (on the level of machine code), although it does take "only 1 operation in Java".
Therefore, yes, you do need synchronization for Boolean.
Please see slides 4-6 of this presentation for code examples.
On a related note, you should not synchronize on a Boolean
Yes. But if it's a flag that is written from one thread only and you want to ensure visibility to all threads, then a cheap alternative is using volatile.
Yes - even though the internal representation of the object (i.e. the actual boolean flag inside the Boolean wrapper) were 64 bit and it could therefore get "split" in a concurrent situation, a boolean can only have one of the two values, right? So plain assignments (get or set) are atomic, but if you're doing anything else (like check-then-act), for instance x = !x, then it's of course not atomic unless synchronized.
From a technical perspective, synchronization is not required for writes in one thread to be perceived in another thread. What you do need is a happens-before edge. It is likely that either volatile or synchronized will be used to achieve the happens-before edge. Both of those techniques result in a synchronized-with edge. So, in practice, you will probably use synchronization to manage the state of your boolean.
Yes. Note that you are not changing the state of the Boolean object. You are only modifying the reference to the Boolean object. Section 17.7 of the language specification states that "writes to and reads of references are always atomic."
Update: Let me expound upon the need for a happens-before edge. Without a happens-before edge, then the changes that one thread makes to the variable are not guaranteed to ever be perceived by the other threads. It is not simply that the change may be perceived at a bad time such as in between a read and a write. The change may never be perceived.
Let's say that we have a boolean variable that we initialize to false. Then we start two threads. The first thread sets the variable to true and stop. The second thread continually checks the variable until it is true, after which it stops. There is no guarantee that the second thread will ever see the variable as true.
Use AtomicBoolean.
No, you don't. But declare the variable volatile so that the values are reflected in all threads that are accessing the boolean. If you look at AtomicBoolean's set(..) method, it doesn't have any synchronization either.
Yes, practically assignment is atomic. Just setting the value does not need synchronization. However, if you want to do something like:
if (!bool) {
bool = false;
}
then you need synchronization (or AtomicBoolean, which is more efficient than synchronization)
http://docs.oracle.com/javase/tutorial/essential/concurrency/atomic.html
says that read and write of primitive variables is atomic.
Hence it is possible to enforce strict alternation or happens after relationships using boolean (or volatile boolean in case of cache effects)
even if it was atomic there are still syncronization isues since you will propably check the value sometime
e.g.
if (boolVar==true)
-> other thread takes control
do_something();