Does access/write to Boolean object needs synchronization - java

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();

Related

How to avoid using volatile in Java

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

Q: Code isnt working without syncronized method [duplicate]

I have a class that contains a boolean field like this one:
public class MyClass
{
private bool boolVal;
public bool BoolVal
{
get { return boolVal; }
set { boolVal = value; }
}
}
The field can be read and written from many threads using the property. My question is if I should fence the getter and setter with a lock statement? Or should I simply use the volatile keyword and save the locking? Or should I totally ignore multithreading since getting and setting boolean values atomic?
regards,
There are several issues here.
The simple first. Yes, reading and writing a boolean variable is an atomic operation. (clarification: What I mean is that read and write operations by themselves are atomic operations for booleans, not reading and writing, that will of course generate two operations, which together will not be atomic)
However, unless you take extra steps, the compiler might optimize away such reading and writing, or move the operations around, which could make your code operate differently from what you intend.
Marking the field as volatile means that the operations will not be optimized away, the directive basically says that the compiler should never assume the value in this field is the same as the previous one, even if it just read it in the previous instruction.
However, on multicore and multicpu machines, different cores and cpus might have a different value for the field in their cache, and thus you add a lock { } clause, or anything else that forces a memory barrier. This will ensure that the field value is consistent across cores. Additionally, reads and writes will not move past a memory barrier in the code, which means you have predictability in where the operations happen.
So if you suspect, or know, that this field will be written to and read from multiple threads, I would definitely add locking and volatile to the mix.
Note that I'm no expert in multithreading, I'm able to hold my own, but I usually program defensively. There might (I would assume it is highly likely) that you can implement something that doesn't use a lock (there are many lock-free constructs), but sadly I'm not experienced enough in this topic to handle those things. Thus my advice is to add both a lock clause and a volatile directive.
volatile alone is not enough and serves for a different purpose, lock should be fine, but in the end it depends if anyone is going to set boolVal in MyClass iself, who knows, you may have a worker thread spinning in there. It also depends and how you are using boolVal internally. You may also need protection elsewhere. If you ask me, if you are not DEAD SURE you are going to use MyClass in more than one thread, then it's not worth even thinking about it.
P.S. you may also want to read this section

volatile in java with long, int, boolean, and many different cases of write

I have an exam coming up in a concurrent programming class. The class is fairly well structured, but I feel I must not understand the "volatile" keyword as well as I thought. I have read through other posts on how it works, and it seems to make sense, but my understanding of Java as a whole is limiting me. These are practice questions T/F, would anyone mind answering them and explaining why they are True or false? I have put my best guesses and explanations in
a. ____An int variable count is shared among several threads,
where the only actions on count are to read its value, and to increment it.
It suffices to mark count as volatile.
false, volatile keyword ensures that there are no local caches of this variable, but a race condition can still occur because the new value depends on the previous for count(and the operation is therefore not atomic), so two threads can read the value, increment it and there is still a race condition on write back. If count was not dependent on previous value (such as just an ID number that is written) this would work.
b. ____ The long variable count is shared among several threads,
where the only actions on count it are to read its value, and to increment
it. It suffices to mark count as volatile.
same as above, except even if the value is not dependent on previous values, this is not thread safe, since it is NEVER an atomic operation because long takes two write cycles for the upper and lower 32 bit writes and reads
c. ____ The boolean variable b, initially false, is shared between
multiple threads. One specific thread sets its value to true, the other
threads read the value. It suffices to mark b as volatile.
true, changing the boolean is atomic and can occur before an interrupt occurs, and updates for all other threads.
d. ____ The boolean variable b is shared between multiple threads.
Any thread can set or read its value. Once b is set to true, it remains true
henceforth. It suffices to mark b as volatile.
true, same reason as above.
Thanks so much!
a. your answer is fine (i.e. volatile is not enough)
b. "it is NEVER an atomic operation because long takes two write cycles for the upper and lower 32 bit writes and reads" => that is too strong for non volatile variables: non volatile long assignment may or may not be atomic. It is generally atomic on 64-bit processors but the Java Memory Model does not give any guarantees. However volatile long assignment is guaranteed to be atomic.
c. your answer is fine (although I don't understand what you mean by "before an interrupt occurs")
d. your answer is fine
Question D reminds me of why I hate T/F questions. It looks so similar to question C, and yet, if you changed it just a bit, it would be an entirely different, and interesting question:
e: Boolean var, initially false, Any thread may set it true, but it must only be set one time.
That is called the consensus problem: How do the threads choose which one among them gets to set the flag? In that case, volatile alone is not sufficient.
The consensus problem is fundamental to understanding multiprocessing. If you can't solve the consensus problem, then you can't have mutual exclusion, you can't have multiple consumer queues or multiple provider queues,... If you can't solve the consensus problem, then you really can't provide any correctness guarantees at all.
Did the author of question D have the consensus problem in mind? It's a tough call to make when you answer is limited to either T or F.

Does volatile influence non-volatile variables?

Okay, suppose I have a bunch of variables, one of them declared volatile:
int a;
int b;
int c;
volatile int v;
If one thread writes to all four variables (writing to v last), and another thread reads from all four variables (reading from v first), does that second thread see the values written to a, b and c by the first thread, even though they are not themselves declared volatile? Or can it possibly see stale values?
Since there seems to be some confusion: I'm not deliberately trying to do something unsafe. I just want to understand the Java memory model and the semantics of the volatile keyword. Pure curiosity.
I'm going to speak to what I think you may really be probing about—piggybacking synchronization.
The technique that it looks like you're trying to use involves using one volatile variable as a synchronization guard in concert with one or more other non-volatile variables. This technique is applicable when the following conditions hold true:
Only one thread will write to the set of values meant to be guarded.
The threads reading the set of values will read them only if the volatile guard value meets some criteria.
You don't mention the second condition holding true for your example, but we can examine it anyway. The model for the writer is as follows:
Write to all the non-volatile variables, assuming that no other thread will try to read them.
Once complete, write a value to the volatile guard variable that indicates that the readers' criteria is met.
The readers operate as follows:
Read the volatile guard variable at any time, and if its value meets the criteria, then
Read the other non-volatile variables.
The readers must not read the other non-volatile variables if the volatile guard variable does not yet indicate a proper value.
The guard variable is acting as a gate. It's closed until the writer sets it to a particular value, or set of values that all meet the criteria of indicating that the gate is now open. The non-volatile variables are guarded behind the gate. The reader is not permitted to read them until the gate opens. Once the gate is open, the reader will see a consistent view of the set of non-volatile variables.
Note that it is not safe to run this protocol repeatedly. The writer can't keep changing the non-volatile variables once it's opened the gate. At that point, multiple reader threads may be reading those other variables, and they can—though are not guaranteed—see updates to those variables. Seeing some but not all of those updates would yield inconsistent views of the set.
Backing up, the trick here is to control access to a set of variables without either
creating a structure to hold them all, to which an atomic reference could be swapped, um, atomically, or
using a lock to make writing to and reading from the entire set of variables mutually exclusive activities.
Piggybacking on top of the volatile guard variable is a clever stunt—not one to be done casually. Subsequent updates to the program can break the aforementioned fragile conditions, removing the consistency guarantees afforded by the Java memory model. Should you choose to use this technique, document its invariants and requirements in the code clearly.
Yes. volatile, locks, etc., setup the happens-before relationship, but it affects all variables (in the new Java Memory Model (JMM) from Java SE 5/JDK 1.4). Kind of makes it useful for non-primitive volatiles...
does that second thread see the values written to a, b and c by the first thread, even though they are not themselves declared volatile? Or can it possibly see stale values?
You will get stale reads, b/c you can't ensure that the values of a, b, c are the ones set after reading of v. Using state machine (but you need CAS to change the state) is a way to tackle similar issues but it's beyond the scope of the discussion.
Perhaps this part is unclear, after writing to v and reading first from v, you'd get the right results (non-stale reads), the main issue is that if you do
if (v==STATE1){...proceed...}, there is no guarantee some other thread would not be modifying the state of a/b/c. In that case, there will be state reads.
If you modify the a/b/c+v once only you'd get the correct result.
Mastering concurrency and and lock-free structures is a really hard one. Doug Lea has a good book on and most talks/articles of Dr. Cliff Click are a wonderful wealth, if you need something to start digging in.
Yes, volatile write "happens-before" next volatile read on the same variable.
While #seh is right on about consistency problems with multiple variables, there are use cases that less consistency is required.
For example, a writer thread updates some state variables; a reader thread displays them promptly. There's not much relation among the variables, we only care about reading the new values promptly. We could make every state variable volatile. Or we could use only one volatile variable as visibility guard.
However, the saving is only on the paper, performance wise there's hardly any difference. In either version, every state variable must be "flushed" by the writer and "loaded" by the reader. No free lunch.

java threads synchronization

In the class below, is the method getIt() thread safe and why?
public class X {
private long myVar;
public void setIt(long var){
myVar = var;
}
public long getIt() {
return myVar;
}
}
It is not thread-safe. Variables of type long and double in Java are treated as two separate 32-bit variables. One thread could be writing and have written half the value when another thread reads both halves. In this situation, the reader would see a value that was never supposed to exist.
To make this thread-safe you can either declare myVar as volatile (Java 1.5 or later) or make both setIt and getIt synchronized.
Note that even if myVar was a 32-bit int you could still run into threading issues where one thread could be reading an out of date value that another thread has changed. This could occur because the value has been cached by the CPU. To resolve this, you again need to declare myVar as volatile (Java 1.5 or later) or make both setIt and getIt synchronized.
It's also worth noting that if you are using the result of getIt in a subsequent setIt call, e.g. x.setIt(x.getIt() * 2), then you probably want to synchronize across both calls:
synchronized(x)
{
x.setIt(x.getIt() * 2);
}
Without the extra synchronization, another thread could change the value in between the getIt and setIt calls causing the other thread's value to be lost.
This is not thread-safe. Even if your platform guarantees atomic writes of long, the lack of synchronized makes it possible that one thread calls setIt() and even after this call has finished it is possible that another thread can call getIt() and this call could return the old value of myVar.
The synchronized keyword does more than an exclusive access of one thread to a block or a method. It also guarantees that the second thread is informed about a change of a variable.
So you either have to mark both methods as synchronized or mark the member myVar as volatile.
There's a very good explanation about synchronization here:
Atomic actions cannot be interleaved, so they can be used without fear of thread interference. However, this does not eliminate all need to synchronize atomic actions, because memory consistency errors are still possible. Using volatile variables reduces the risk of memory consistency errors, because any write to a volatile variable establishes a happens-before relationship with subsequent reads of that same variable. 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.
No, it's not. At least, not on platforms that lack atomic 64-bit memory accesses.
Suppose that Thread A calls setIt, copies 32 bits into memory where the backing value is, and is then pre-empted before it can copy the other 32 bits.
Then Thread B calls getIt.
No it is not, because longs are not atomic in java, so one thread could have written 32 bits of the long in the setIt method, and then the getIt could read the value, and then setIt could set the other 32 bits.
So the end result is that getIt returns a value that was never valid.
It ought to be, and generally is, but is not guaranteed to be thread safe. There could be issues with different cores having different versions in CPU cache, or the store/retrieve not being atomic for all architectures. Use the AtomicLong class.
The getter is not thread safe because it’s not guarded by any mechanism that guarantees the most up-to-date visibility. Your choices are:
making myVar final (but then you can’t mutate it)
making myVar volatile
use synchronized to accessing myVar
AFAIK, Modern JVMs no longer split long and double operations. I don't know of any reference which states this is still a problem. For example, see AtomicLong which doesn't use synchronization in Sun's JVM.
Assuming you want to be sure it is not a problem then you can use synchronize both get() and set(). However, if you are performing an operation like add, i.e. set(get()+1) then this synchronization doesn't buy you much, you still have to synchronize the object for the whole operation. (A better way around this is to use a single operation for add(n) which is synchronized)
However, a better solution is to use an AtomicLong. This supports atomic operations like get, set and add and DOESN'T use synchronization.
Since it is a read only method. You should synchronize the set method.
EDIT : I see why the get method needs to be synchronized as well. Good job explaining Phil Ross.

Categories