views:

255

answers:

6

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.

  1. Do I need to have a synchronization for this boolean?
  2. 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.

+2  A: 

Use AtomicBoolean.

Chuk Lee
thanks, 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.
Suraj Chandran
Depends on the internal representation of the object right 32bit or 64bit? I think the latter will definitely have issues. Not sure about 32bit though. Just to be safe synchronize them. If it is just one object then AtomicXXXX is faster than synchronized
Chuk Lee
+6  A: 

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

DVK
+1 for good reference
Chuk Lee
@DVK...."you should not synchronize on a Boolean".....can gerenalize it and say that never synchronize on non-final objects.
Suraj Chandran
Is x=true; atomic or not? x is Boolean
Suraj Chandran
@Suraj: The guidelines (1) that you should not synchronize on a Boolean and (2) that you should not synchronzie on non-final objects are not overlapping guidelines. Even if your Boolean variable is final, you should still not be using it as your synchronization object.
Matthew T. Staebler
@Aeth....why? If my Boolean is final, then there is no problem in using it as lock right?
Suraj Chandran
@Suraj: No, you still should not use it as the lock. Remember that the lock is based upon the *object* not the *reference* to the object. Depending upon how you obtained it, the reference to the Boolean may point to an object that is shared with other references. For example, it is perfectly valid--and very likely--that `Boolean.TRUE`, `(Boolean) true`, and `Boolean.valueOf(true)` will all reference the same object.
Matthew T. Staebler
@Suraj: As a general rule of thumb, I would recommend that you either use a basic `Object` object as a lock or use one of the locks from the `java.utils.concurrent.locks` package. At a minimum, the class that needs to ultimately use the lock should have full control over the scope of the lock and limit that scope to that of the class. You can do that with a `Boolean` if you limit yourself to using the `Boolean` constructor to obtain objects, but it will likely be a perilous--and ultimately fruitless--endeavor.
Matthew T. Staebler
@DVK: `Boolean` objects are immutable. All the methods of `Boolean` objects most assuredly *are* atomic.
Matthew T. Staebler
+1  A: 
  1. 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.

  2. 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.

Joonas Pulakka
Why is `volatile` not a valid solution if the flag is being written to more than one thread?
Matthew T. Staebler
@Aeth: It can be a valid solution in some situations, but it lacks AtomicBoolean's compareAndSet operations / similar functionality achieved by using synchronization. If the value of write depends on the variable's current value, then `volatile` isn't an option for multithread-write. But it has its uses, of course.
Joonas Pulakka
+3  A: 
  1. 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.
  2. 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.

Matthew T. Staebler
A: 

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

jimkont
A: 
  1. 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.

  2. 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)

Bozho