I often use the following pattern to create a cancellable thread:
public class CounterLoop implements Runnable {
private volatile AtomicBoolean cancelPending = new AtomicBoolean(false);
#Override
public void run() {
while (!cancelPending.get()) {
//count
}
}
public void cancel() {
cancelPending.set(true);
}
}
But I'm not sure that cancelPending MUST be a AtomicBoolean. Can we just use a normal boolean in this case?
Using both volatile and AtomicBoolean is unnecessary. If you declare the cancelPending variable as final as follows:
private final AtomicBoolean cancelPending = new AtomicBoolean(false);
the JLS semantics for final fields mean that synchronization (or volatile) will not be needed. All threads will see the correct value for the cancelPending reference. JLS 17.5 states:
"An object is considered to be completely initialized when its constructor finishes. A thread that can only see a reference to an object after that object has been completely initialized is guaranteed to see the correctly initialized values for that object's final fields."
... but there are no such guarantees for normal fields; i.e. not final and not volatile.
You could also just declare cancelPending as a volatile boolean ... since you don't appear to be using the test-and-set capability of AtomicBoolean.
However, if you used a non-volatile boolean you would need to use synchronized to ensure that all threads see an up-to-date copy of the cancelPending flag.
You can use a volatile boolean instead with no issues.
Note that this only applies in cases much like this where the boolean is only being changed to a specific value (true in this case). If the boolean might be changed to either true or false at any time then you may need an AtomicBoolean to detect and act on race conditions.
However - the pattern you describe has an innate smell. By looping on a boolean (volatile or not) you are likely to find yourself trying to insert some sort of sleep mechanism or having to interrupt your thread.
A much cleaner route is to split up the process into finer steps. I recently posted an answer here covering the options of pausing threads that may be of interest.
No, you can not. Because if you will change the boolean value from another thread without proper synchronization then this change can be invisible to another threads. You can use valotile boolean in your case to make any modification visible to all threads.
Yes you can. You can either use a non volatile AtomicBoolean (relying on its built in thread safety), or use any other volatile variable.
According to the Java Memory Model (JMM), both options result in a properly synchronized program, where the read and write of the cancelPending variable can't produce a data race.
Using a volatile boolean variable in this context is safe, though some may consider it bad practice. Consult this thread to see why.
Your solution of using an Atomic* variable seems the best option, even though the synchronization may introduce unnecessary overhead in comparison to a volatile variable.
You can also use a critical section
Object lock = new Object();
#Override
public void run() {
synchronized (lock) {
if (cancelPending) {
return;
}
}
}
or a synchronized method.
synchronized public boolean shouldStop() {
return shouldStop;
}
synchronized public void setStop(boolean stop) {
shouldStop = stop;
}
Related
I understand the code section below is problematic because the new value of isAlive set in the kill method might not be visible in the thread.
public class MyClass extends Thread {
private boolean isAlive;
public void run() {
while(isAlive) {
....
}
}
public void kill() {
isAlive = false;
}
}
The typical fix is to declare the isAlive variable as volatile.
My question here is that is there any other ways to achieve this without using volatile? Does Java provide other mechanisms to achieve this?
EDIT: Synchronize the method is also not an option.
There is no good reason to go for a different option than volatile. Volatile is needed to provide the appropriate happens-before edge between writing and reading; otherwise you have a data-race on your hands and as a consequence the write to the flag might never be seen. E.g. the compiler could hoist the read of the variable out of a loop.
There are cheaper alternative that provide more relaxed ordering guarantees compared to the sequential consistency that volatile provides. E.g. acquire/release or opaque (check out the Atomic classes and the VarHandle). But this should only be used in very rare situations where the ordering constraints reduce performance due to limited compiler optimizations and fences on a hardware level.
Long story short: make the variable volatile because it a simple and very fast solution.
There are three options:
Make the shared variable volatile. (This is the simplest way.)
Use synchronized, either in the form of synchronized methods or synchronized blocks. Note that you need to do both reads and writes for the shared variables while holding the (same) mutex.
Use one of the classes in java.util.concurrent that has a "synchronizing effect"1. Or more precisely, one that you can use to get a happens before relationship between the update and subsequent read of the isAlive variable. This will be documented in the respective classes javadocs.
If you don't use one of those options, it is not guaranteed2 that the thread that calls run() will see isAlive variable change from true to false.
If you want to understand the deep technical reasons why this is so, read Chapter 17.4 of the Java Language Specification where it specifies the Java Memory Model. (It will explain what happens before means in this context.)
1 - One of the Lock classes would be an obvious choice.
2 - That is to say ... your code may not work 100% reliably on all platforms. This is the kind of problem where "try it and see" or even extensive testing cannot show conclusively that your code is correct.
The wait/notify mechanism is embedded deep in the heart of the java language, the superclass of classes, has five methods that are the core of the wait/notify mechanism, notify(), notifyAll(), wait(), wait(long), and wait(long, int), all classes in java inherit from Object, in addition, none of these methods can be overridden in a subclass as they are all declared final
here is an example that may help you to understand the concept
public class NotifyAndWait {
public List list;
public NofityAndWait() { list = Collections.synchronizedList(new LinkedList ());
public String removeItem() throws InterruptedException {
synchronized(list) {
while(list.isEmpty())
list.wait();
}
String item = list.remove(0);
return item;
}
public void addItem(String item) {
synchronized(list) {
list.add(item);
//after adding, nofity and waiting all thread that the list has changed
list.notifyAll();
}
}
public static void main(String..args) throws Exception {
final NotifyAndWait obj = new NotifyAndWait();
Runnable runA = new Runnable() {
public void run() {
try {
String item = enf.removeItem();
catch(Exception e) {} };
Runnable runB = new Runnable() {
public void run() { obj.addItem("Hello"); }
};
Thread t1 = new Thread(runA, "T1");
t1.start();
Thread.sleep(500);
Thread t2 = new Thread(runB, "T2");
t2.start();
Thread.sleep(1000);
}
}
As far as I know, polling a boolean in a while loop as a "kill" control is a perfectly reasonable thing to do. Brian Goetz, in "Java Concurrency in Action" has a code example that is very similar to yours, on page 137 (section 7.1 Task Cancellation).
He states that making the boolean volatile gives the pattern greater reliability. He has a good description of the mechanism on page 38.
When a field is declared volatile, the compile and runtime are put on
notice that this variable is shared and that operations on it should
not be reordered with other memory operations. Volatile variables are
not cached in registers or in caches where they are hidden from other
processors, so a read of a volatile variable always returns the most
recent write by any thread.
I use volatile booleans and loose coupling as my main method of communication that must occur across threads. AFAIK, volatile has a smaller cost than synchronized and is the most recommended pattern for this situation.
My understanding: Declaring a variable volatile guarantees the visibility for other threads about writes to that variable. Essentially, every write to volatile variable happens-before subsequent reads.
I understand the atomicity of AtomicBoolean.compareAndSet() and how it provides the atomicity of read+write operation that volatile doesn't. But I don't see any doc providing visibility guarantee by AtomicBoolean like the following:
Every successful write by AtomicBoolean.compareAndSet() will eventually be visible to subsequent AtomicBoolean.get() and AtomicBoolean.compareAndSet() by other threads.
But, I keep seeing code labelled as thread-safe which are like this,
// default false so that first-thread that execute() can enter the logic block
private static final AtomicBoolean executing = new AtomicBoolean(false);
public void execute() {
if (executing.compareAndSet(false, true)) { // check if the executing is previously false and if so update it to true
try {
// thead-safe code, i.e only one thread guaranteed to execute at any point of time time
} finally {
executing.set(false); // executing thread now re-sets the test value
}
}
}
Shouldn't the variable executing also declared volatile, like private static volatile AtomicBoolean executing = new AtomicBoolean(false); ? So the visibility guarantee needed by AtomicBoolean is achieved?
Is it necessary to make AtomicBoolean also volatile?
No.
In the example, executing is declared as static final, so it will be initialized once at class initialization time and safely published to any other code that needs it.
This behavior is guaranteed because there is a happens-before between a classes initialization completing (normally) and any subsequent use of any static variable declared by the class. The fact that the variable is also final excludes any subsequent assignments to the static that would negate the happens-before.
You would only need to declare executing as volatile if something could assign a new value to it after initialization. That's not possible here without doing some nasty reflection. (And the JLS states that if you do that kind of thing to change a final, the memory model guarantees do not apply.)
You would get a similar effect if executing was final but an instance field rather than a static field. The reasoning is slightly different, but it is also explicitly mentioned in the JLS.
Finally, the Java syntax does not allow you to combine volatile and final modifiers. That combination doesn't make sense.
We cannot use the below code
private static volatile final AtomicBoolean executing = new AtomicBoolean(false);
Usage of volatile and final together is invalid. As stated by #RealSkeptic var which would never change (final) need not have volatile. Volatile is used for those vars whose values gets changed in runtime by one or more thread.
//Happy learning
I am trying to understand the difference between the two following code blocks
AtomicBoolean ab = new AtomicBoolean(false);
using the following to get and set state. .
ab.get();
ab.set(X);
vs.
private boolean ab = false;
private final Object myboollock = new Ojbect();
public void setAB(boolean state)
{
synchronized(myboollock)
{
ab = state;
}
}
public boolean getAB()
{
synchronized(myboollock)
{
return ab;
}
}
I need to thread protect a boolean, that is all, and have
in the past used the later method, but would like to start to use Atomic
objects, (if ) they are safe?,
If all you're trying to do is make getting and setting a single boolean value atomic, then yes - you can use AtomicBoolean instead without any synchronization.
Of course, synchronized allows a far wider range of uses, such as performing several actions within the block without losing the lock, or using it for wait/notify. So it's not like AtomicBoolean is a general alternative to synchronization - but in this case you can use it instead of synchronization.
There are a few subtle differences but seen from the outside the two code snippets behave similarly: if you call the set method, the change will be visible to other threads calling get subsequently.
The main differences are:
performance: depending on the level of contention, you may get better performance with synchronized or AtomicBoolean
atomicity: if at some stage you want to do more than just setting the boolean value, a synchronized block will allow you to add instructions atomically but AtomicBoolean won't
I read some java code, and found these functions:
synchronized void setConnected(boolean connected){
this.connected = connected;
}
synchronized boolean isConnected(){
return connected;
}
I wonder if synchronization makes any sense here, or just author didn't understand the need for synchronized keyword?
I'd suppose that synchronized is useless here. Or am I mistaken?
The keyword synchronized is one way of ensuring thread-safety. Beware: there's (way) more to thread-safety than deadlocks, or missing updates because of two threads incrementing an int without synchronization.
Consider the following class:
class Connection {
private boolean connected;
synchronized void setConnected(boolean connected){
this.connected = connected;
}
synchronized boolean isConnected(){
return connected;
}
}
If multiple threads share an instance of Connection and one thread calls setConnected(true), without synchronized it is possible that other threads keep seeing isConnected() == false. The synchronized keyword guarantees that all threads sees the current value of the field.
In more technical terms, the synchronized keyword ensures a memory barrier (hint: google that).
In more details: every write made before releasing a monitor (ie, before leaving a synchronized block) is guaranteed to be seen by every read made after acquiring the same monitor (ie, after entering a block synchronizing on the same object). In Java, there's something called happens-before (hint: google that), which is not as trivial as "I wrote the code in this order, so things get executed in this order". Using synchronized is a way to establish a happens-before relationship and guarantee that threads see the memory as you would expect them to see.
Another way to achieve the same guarantees, in this case, would be to eliminate the synchronized keyword and mark the field volatile. The guarantees provided by volatile are as follows: all writes made by a thread before a volatile write are guaranteed to be visible to a thread after a subsequent volatile read of the same field.
As a final note, in this particular case it might be better to use a volatile field instead of synchronized accessors, because the two approaches provide the same guarantees and the volatile-field approach allows simultaneous accesses to the field from different threads (which might improve performance if the synchronized version has too much contention).
Synchronization is needed here to prevent memory consistency errors, see http://docs.oracle.com/javase/tutorial/essential/concurrency/memconsist.html. Though in this concrete case volatile would be much more efficient solution
private volatile boolean connected;
void setConnected(boolean connected){
this.connected = connected;
}
boolean isConnected(){
return connected;
}
The author has probably designed the code with a multi-threaded approach in mind. This means that the methods are synchronized and more than one thread will not be able to access the synchronized code at the same time on the same object instance.
I write a thread class called T.
My purpose is to make sure only one thread object running at a time.
So when the thread object is called, it would check a boolean flag called BUSY.
My question is what is the different between
private static AtomicBoolean BUSY = new AtomicBoolean(false);
and
private static boolean BUSY = false;
I thought if using the 'static', all object would only check one BUSY boolean variable so that would make sure only one thread object is running.
You must at least make the boolean variable volatile and the AtomicBoolean variable final in order to have a comparable solution. After you do that, there will be no difference for your use case.
The difference comes about if you use AtomicBoolean's getAndSet or compareAndSet methods, which combine one read and one write action into an atomic whole, wheraas these are not atomic when done against a volatile.
You can use a boolean and with proper synchronization (and making volatile) can achieve what you need.
But by using the AtomicBoolean you can check the current value atomically without the need to write code for synchronization yourself
As said by others you must make the variables final / volatile respectively.
From what you describe I fear you have a place where you do something like this:
if (!BUSY){
BUSY = true;
}
Note that this is broken in absence of commons synchronization, because two threads might check the flag, both seeing it as false and starting their work.
I suggest looking into the existing structures for handling concurrency: http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/package-summary.html
Especially Semaphore with a single permit might be what you are looking for.
A useful feature of an AtomicBoolean is to allow a single thread to continue if and only if BUSY is false but not to let any other threads to continue.
private static AtomicBoolean BUSY = new AtomicBoolean(false);
public void doWork(){
if(BUSY.compareAndSet(false,true)){
//do some work
BUSY.set(false);
}else{
//some other thread won, return now or retry later?
}
}
So here only one thread will doWork at any given time. You cannot achieve this with a volatile boolean because you cannot be sure that Thread.currentThread() set the boolean.