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
Related
I am recently reading the book "Java Concurrency in Practice". One example of "safe publish" it gives is to initialize a private int field n during construction, and a later assertion on that field n == "expect value" through a public method could still be failed if it is called from another thread. This makes me feel worried in that, assuming all private fields are initialized only once, do we still have to mark them as volatile or wrap them into ThreadLocal or even use an AtomicReference to get a pure thread safe java class, since these private fields, though not visible outside, definitely could be referenced by the method(s) called by other threads.
EDIT: Just to be clear - the assertion is failed because the calling thread sees a stale value of n, even though it has been set during construction. This is a clearly a memory-visibility issue. Problem is whether synchronizing on n is worthy of the overhead after all, since it is only initialized once, and as a private field, author can make sure it won't be changed again.
This specific case is properly documented in the JSR 133: Java Memory Model and Thread
Specification. It even has a dedicated code sample page 14 section 3.5 Final Fields that exactly match your question.
To summarize:
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.
There is no guarantee for non final fields
It means that you have to make sure that an happens-before occurs between your object creation in a thread and its usage in another thread. You can use synchronized, volatile or any other mean to enforce an happens-before.
Since you say in another comment that the field is only set during construction, I would make it... final. Also, such shared objects between threads could suggest some design smell; I would review my design to make sure that I am not creating an overly complex, tightly coupled, hard to debug system.
If the fields are never used outside the class, wrapping their usages with synchronized blocks or inside synchronized functions, two threads won't concurrently modify these fields.
volatile keyword is just a part of thread safety. It only makes the value of a field never be cached, always read from memory. Take this example.
private int myPrivateField = 0;
void someFunction() {
while(myPrivateField ==0) {
}
}
void otherFunction() {
myPrivateField = 1;
}
If someFunction() is called from one thread and it's running for a while,
when you call otherFunction() the value of myPrivateField will not be
"updated" inside someFunction, it was cached to 0 as an otimization.
Making myPrivateField as volatile, the value will always be the one
in memory.
For the example, there won't be much difference for the functions be
synchronized, but without synchronization, you can read a value in an
inconsistent state.
Only final fields are guaranteed to be visible after constructor. Any other field requires some visibility mechanism, such as synchronized or volatile.
This is not as much of a burden as it seems: if the field is not final, then it can be changed by another thread while you're reading it. If teh field can be changed, then the last assigned value must be propagated from the writer thread to the reader thread, whether the writer thread called the constructor or a setter.
If the change in this field is not related to any other field in the class, then the field should be volatile. If the field is related to other fields in the class, then use synchronized or other, more modern locking primitives.
Not answering the entire question, but it should be pointed out that using ThreadLocal is exactly the wrong thing to use if you want to ensure visibility of updated values in all threads. Consider the following code:
class Test {
private static final ThreadLocal<Integer> value = new ThreadLocal<>();
public static void main(String[] args) throws InterruptedException {
System.out.println("From main Thread, value is " + value.get());
value.set(42);
System.out.println("Value has been changed");
Thread t = new Thread() {
public void run() {
System.out.println("From other Thread, value is " + value.get());
}
};
t.start();
t.join();
System.out.println("From main Thread, value is " + value.get());
}
}
This will output the following:
From main Thread, value is null
Value has been changed
From other Thread, value is null
From main Thread, value is 42
i.e. the other thread doesn't see the updated value. This is because changes to the value of a ThreadLocal is, by definition, localized to the thread which changes it.
My personal preference would be to use AtomicReference, since this avoids the risk of forgetting to synchronize externally; it also allows things like atomic compare-and-set, which you don't get with a volatile variable. However, this may not be a requirement for your particular application.
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;
}
Basically the following works but since I read about the final keyword I am not sure anymore if I have to declare name final if different threads access it?
Thanks in advance.
public class Test4 {
// to ensure thread-safety do we have to declare the variable name final ?
private String name;
public Test4 (String name) {
this.name = name;
}
public void start() {
new MyThread().start();
}
private class MyThread extends Thread {
public void run() {
System.out.println(name);
}
}
public static void main(String[] args) {
Test4 t = new Test4("Don't know if I am threadsafe");
t.start();
}
}
The final modifier - while preventing the member from being re-assigned - does not affect the correctness of the given code1
From the the 17.4.4 Synchronization Order section for the Java 5 Language Specification:
A synchronization order is a total order over all of the synchronization actions of an execution .. Synchronization actions induce the synchronized-with relation on actions, defined as follows:
..
An action that starts a thread synchronizes-with the first action in the thread it starts.
..
Then, since the thread that sets the name member is the one that starts the thread, the synchronization order is guaranteed. (Synchronizes-with implies a Happens-before ordering.)
Note that:
The member name needs only be set before starting the thread: that is, it does not need to be set in the constructor for this synchronizes-with guarantee.
This does not guarantee synchronization ordering - and thus it does not guarantee happens-before or value visibility - between already running threads or threads created elsewhere!
However, final fields do give a much more comfortable feeling (ref. 17.5 Final Field Semantics):
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.
In this case, with final fields, the value is guaranteed to be visible on every thread after the constructor completes. (This guarantee can be violated by "constructor leaks".)
1 In the supplied code the "non-final" name member is only assigned once before the thread is started.
In different, less trivial, programs other synchronization issues may be exposed. This answer examines if removing final alters the correctness of the supplied code.
All that being said, I consider it "good practice" to use both immutable variables (final) and immutable objects - especially when dealing with threads. Instead of needing to know the little arcane details of the JVM, do the safe proven things and strive for obvious correctness over cleverness or "performance".
See also:
Synchronizing an object shared across threads, but not accessed concurrently
When does java thread cache refresh happens?
Java happend before thread start
final variables are immutable, you can not change the value once it is constructed so it does not have concurrency issue.
You will not get the correct value of the field without final.
Maybe the thread got the old value after you changing the value of field.
Check the Visibility of JMM.
Another link of volatile.
Happends-Before Rule.
Happends-Before in JMM.
Could you be looking for an AtomicReference or perhaps volatile? It depends what you mean by thread safe?
// Atomic to allow deeper control of updates.
private AtomicReference<String> name = new AtomicReference<String>();
// Volatile to ensure it is not cached.
private volatile String vName;
public Test(String name) {
this.name.set(name);
this.vName = name;
}
public void start() {
new MyThread().start();
}
private class MyThread extends Thread {
public void run() {
System.out.println(name.get());
System.out.println(vName);
}
}
final doesn't have nothing with multithreading, but you should put final if your fild shouldn't be changed and is initialized in constructor of class. This means that fild can't be changed latter.
since String is immutable and you declare the field final ,with all threads accessing it after the field assignment, then surely there will be no concurrent issues since the field would be used only for Read operation,in contrast to the case where StringBuilder were used.
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.
If in a class I have a ConcurrentHashMap instance that will be modified and read by multiple threads I might define like this:
public class My Class {
private volatile ConcurrentHashMap<String,String> myMap = new ConcurrentHashMap<String,String>();
...
}
adding final to the myMap field results in an error saying I can only use final or volatile. Why can it not be both?
volatile only has relevance to modifications of the variable itself, not the object it refers to. It makes no sense to have a final volatile field because final fields cannot be modified. Just declare the field final and it should be fine.
It's because of Java Memory Model (JMM).
Essentially, when you declare object field as final you need to initialize it in object's constructor and then final field won't change it's value. And JMM promises that after ctor is finished any thread will see the same (correct) value of final field. So, you won't need to use explicit synchronization, such as synchronize or Lock to allow all threads to see correct value of final field.
When you declare object's field as volatile, field's value can change, but still every read of value from any thread will see latest value written to it.
So, final and volatile achieve same purpose -- visibility of object's field value, but first is specifically used for a variable may only be assigned to once and second is used for a variable that can be changed many times.
References:
http://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.12.4
http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.3.1.4
Because volatile and final are two extreme ends in Java
volatile means the variable is bound to changes
final means the value of the variable will never change whatsoever
volatile is used for variables that their value may change, in certain cases, otherwise there is no need for volatile, and final means that the variable may not change, so there's no need for volatile.
Your concurrency concerns are important, but making the HashMap volatile will not solve the problem, for handling the concurrency issues, you already use ConcurrentHashMap.
A volatile field gives you guarantees as what happens when you change it. (No an object which it might be a reference to)
A final field cannot be changed (What the fields reference can be changed)
It makes no sense to have both.
volatile modifier guarantees that all reads and writes go straight to main memory, i.e. like the variable access is almost into synchronized block. This is irrelevant for final variable that cannot be changed.
Because it doesn't make any sense. Volatile affects object reference value, not the object's fields/etc.
In your situation (you have concurrent map) you should do the field final.
In a multithread environment different threads will read a variable from main memory and add it to the CPU cache. It may result in two different threads making changes on the same variable, while ignoring each others results.
enter image description here
We use word volatile to indicate that variable will be saved in main memory and will be read from main memory. Thus whenever a thread want to read/write a variable it will be done from main memory, essentially making a variable safe in multithread environment.
When we use final keyword we indicate that variable will not change. As you can see if a variable is unchangeable, than it doesn't matter if multiple threads will use it. No thread can change the variable, so even if variable is saved to CPU caches at different times, and threads will use this variable at different times than it's still ok, because the variable can only be read.