Does explicit lock automatically provide memory visibility? - java

Sample code:
class Sample{
private int v;
public void setV(){
Lock a=new Lock();
a.lock();
try{
v=1;
}finally{
a.unlock();
}
}
public int getV(){
return v;
}
}
If I have a thread constantly invoke getV and I just do setV once in another thread, Is that reading thread guaranteed to see the new value right after writing? Or do I need to make "V" volatile or AtomicReference?
If the answer is no, then should I change it into:
class Sample{
private int v;
private Lock a=new Lock();
public void setV(){
a.lock();
try{
v=1;
}finally{
a.unlock();
}
}
public int getV(){
a.lock();
try{
int r=v;
}finally{
a.unlock();
}
return r;
}
}

From the documentation:
All Lock implementations must enforce the same memory synchronization semantics as provided by the built-in monitor lock:
A successful lock operation acts like a successful monitorEnter action
A successful unlock operation acts like a successful monitorExit action
If you use Lock in both threads (i.e. the reading and the writing ones), the reading thread will see the new value, because monitorEnter flushes the cache. Otherwise, you need to declare the variable volatile to force a read from memory in the reading thread.

As per Brian's Law...
If you are writing a variable that might next be read by another
thread, or reading a variable that might have last been written by
another thread, you must use synchronization, and further, both the
reader and the writer must synchronize using the same monitor lock.
So it would be appropriate to synchronize both the setter and getter......
Or
Use AtomicInteger.incrementAndGet() instead if you want to avoid the lock-unlock block (ie. synchronized block)

If I have a thread constantly invoke getV and I just do setV once in
another thread, Is that reading thread guaranteed to see the new value
right after writing?
NO, the reading thread may just read its own copy (cached automatically by the CPU Core which the reading thread is running on) of V's value, and thus not get the latest value.
Or do I need to make "V" volatile or AtomicReference?
YES, they both works.
Making V volatile simply stop CPU Core from caching V's value, i.e. every read/write operation to variable V must access the main memory, which is slower (about 100x times slower than read from L1 Cache, see interaction_latency for details)
Using V = new AtomicInteger() works because AtomicInteger use a private volatile int value; internally to provide visiblity.
And, it also works if you use lock (Lock object, synchronized block or method; they all works) on reading and writing thread (as your second code segment does), because (according to the Second Edition of The Java ® Virtual Machine Specification section 8.9)
...Locking any lock conceptually flushes all variables from a thread's
working memory, and unlocking any lock forces the writing out to main
memory of all variables that the thread has assigned...
...If a thread uses a particular shared variable only after locking a
particular lock and before the corresponding unlocking of that same
lock, then the thread will read the shared value of that variable from
main memory after the lock operation, if necessary, and will copy back
to main memory the value most recently assigned to that variable
before the unlock operation. This, in conjunction with the mutual
exclusion rules for locks, suffices to guarantee that values are
correctly transmitted from one thread to another through shared
variables...
P.S. the AtomicXXX classes also provide CAS (Compare And Swap) operations which is useful for mutlthread access.
P.P.S. The jvm specification on this topic has not changed since Java 6, so they are not included in jvm specification for java 7, 8, and 9.
P.P.P.S. According to this article, CPU caches are always coherent, whatever from each core's view. The situation in your question is caused by the 'Memory Ordering Buffers', in which the store & load instructions (which are used to write and read data from memory, accordingly) could be re-ordered for performance. In detail, the buffer allows a load instruction to get ahead of an older store instruction, which exactly cause the problem (getV() is put ahead so it read the value before you change it in the other thread). However, in my opinion, this is more difficult to understand, so "cache for different core" (as JVM specs did) could be a better conceptual model.

You should make volatile or an AtomicInteger. That will insure that the reading thread will eventually see the change, and close enough to "right after" for most purposes. And technically you don't need the Lock for a simple atomic update like this. Take a close look at AtomicInteger's API. set(), compareAndSet(), etc... will all set the value to be visible by reading threads atomically.

Explicit locks, synchronized, atomic reference and volatile, all provide memory visibility. Lock and synchronized do so for code block they surround and atomic reference and volatile to the particular variable declared so. However for the visibility to work correctly, both reading and writing methods should be protected by the same locking object.
It will not work in your case because your getter method is not projected by the lock which protects the setter method. If you make the change it will work as required. Also just declaring the variable as volatile or AtomicInteger or AtomicReference<Integer> will work too.

Related

Why do I need to use synchronized for multiple threads over volatile?

Some people says if multiple threads are reading/writing then you need to use synchronized and if one thread is reading/writing and another one is only reading then you must use volatile. I don't get the difference between this situations.
Basically, the value of a volatile field becomes visible to all readers (other threads in particular) after a write operation completes on it.
Then If I define a variable as volatile, first threadA will read its value, threadA will update its value and write it to memory.After that variable will become visible to threadB. Then why do I need to synchronized block?
Some people says if multiple threads are reading/writing then you need to use synchronized and if one thread is reading/writing and another one is only reading then you must use volatile. I don't get the difference between this situations.
There really isn't a hard and fast rule with this. Choosing whether or not to use synchronized or volatile has more to do with how the objects are being updated as opposed to how many readers or writers there are.
For example, you can achieve multiple readers and writers with an AtomicLong which wraps a volatile long.
private AtomicLong counter = new AtomicLong();
...
// many threads can get/set this counter without synchronized
counter.incrementAndGet();
And there are circumstances where you would need a synchronized block even with a single reader/writer.
synchronized (status) {
status.setNumTransactions(dao.getNumTransactions());
// we don't want the reader thread to see `status` partially updated here
status.setTotalMoney(dao.getTotalMoney());
}
In the above example, since we are making multiple calls to update the status object we may need to ensure that other threads don't see it when the num-transactions has been updated but not the total-money. Yes, AtomicReference handles some of these cases but not all.
To be clear, marking a field volatile ensures memory synchronization. When you read a volatile field you cross a read memory barrier and when you write it you cross a write memory barrier. A synchronized block has a read memory barrier at the start and a write barrier at the end of the block and is has mutex locking to ensure only one thread can enter the block at once.
Sometimes you just need memory barriers to achieve proper sharing of data between threads and sometimes you need locking.
As comments suggest, you might do some further reading. But to give you an idea you can take a look at this stackoverflow question and think for example about the following scenario:
You have couple of variables which need to be in the right state. But although you make them all volatile you need time to update them by some code executing.
Exactly this code may be executed almost at the same time by a different thread. The first variables could be "OK" and somehow synchronized but some other maybe dependent on the first ones and are not correct yet. Thus you need a synchronized block in that case.
To add one more post for further reading about volatile look here
The primary difference between volatile and synchronized is that volatile only guarantees visibility whereas synchronized guarantees both visibility and locking.
If there are multiple read threads and one write thread then volatile usage can ensure that changes by the write thread to the volatile variable are visible to other threads immediately. But you see in this case locking isn't a problem because you only have 1 writing thread.
There are certain rules of thumb for a volatile:
Don't use volatile when its value depends on its previous value
Don't use volatile when it participates in interactions with other invariants
Don't use volatile when there are multiple write threads that update value of volatile variable.
In general, use of volatile should be limited to only those cases where it's relatively easy to reason about its state such as in the case of status flags.
In all other cases where you have shared mutable state always use synchronized wherever shared mutable state is being touched unless declared final and modified only in the constructor without unsafe publication. Volatile is a replacement for synchronized only in special cases as described in my 3 points.

Should a method be synchronized if it access a volatile variable? [duplicate]

I am wondering at the difference between declaring a variable as volatile and always accessing the variable in a synchronized(this) block in Java?
According to this article http://www.javamex.com/tutorials/synchronization_volatile.shtml there is a lot to be said and there are many differences but also some similarities.
I am particularly interested in this piece of info:
...
access to a volatile variable never has the potential to block: we're only ever doing a simple read or write, so unlike a synchronized block we will never hold on to any lock;
because accessing a volatile variable never holds a lock, it is not suitable for cases where we want to read-update-write as an atomic operation (unless we're prepared to "miss an update");
What do they mean by read-update-write? Isn't a write also an update or do they simply mean that the update is a write that depends on the read?
Most of all, when is it more suitable to declare variables volatile rather than access them through a synchronized block? Is it a good idea to use volatile for variables that depend on input? For instance, there is a variable called render that is read through the rendering loop and set by a keypress event?
It's important to understand that there are two aspects to thread safety.
execution control, and
memory visibility
The first has to do with controlling when code executes (including the order in which instructions are executed) and whether it can execute concurrently, and the second to do with when the effects in memory of what has been done are visible to other threads. Because each CPU has several levels of cache between it and main memory, threads running on different CPUs or cores can see "memory" differently at any given moment in time because threads are permitted to obtain and work on private copies of main memory.
Using synchronized prevents any other thread from obtaining the monitor (or lock) for the same object, thereby preventing all code blocks protected by synchronization on the same object from executing concurrently. Synchronization also creates a "happens-before" memory barrier, causing a memory visibility constraint such that anything done up to the point some thread releases a lock appears to another thread subsequently acquiring the same lock to have happened before it acquired the lock. In practical terms, on current hardware, this typically causes flushing of the CPU caches when a monitor is acquired and writes to main memory when it is released, both of which are (relatively) expensive.
Using volatile, on the other hand, forces all accesses (read or write) to the volatile variable to occur to main memory, effectively keeping the volatile variable out of CPU caches. This can be useful for some actions where it is simply required that visibility of the variable be correct and order of accesses is not important. Using volatile also changes treatment of long and double to require accesses to them to be atomic; on some (older) hardware this might require locks, though not on modern 64 bit hardware. Under the new (JSR-133) memory model for Java 5+, the semantics of volatile have been strengthened to be almost as strong as synchronized with respect to memory visibility and instruction ordering (see http://www.cs.umd.edu/users/pugh/java/memoryModel/jsr-133-faq.html#volatile). For the purposes of visibility, each access to a volatile field acts like half a synchronization.
Under the new memory model, it is still true that volatile variables cannot be reordered with each other. The difference is that it is now no longer so easy to reorder normal field accesses around them. Writing to a volatile field has the same memory effect as a monitor release, and reading from a volatile field has the same memory effect as a monitor acquire. In effect, because the new memory model places stricter constraints on reordering of volatile field accesses with other field accesses, volatile or not, anything that was visible to thread A when it writes to volatile field f becomes visible to thread B when it reads f.
-- JSR 133 (Java Memory Model) FAQ
So, now both forms of memory barrier (under the current JMM) cause an instruction re-ordering barrier which prevents the compiler or run-time from re-ordering instructions across the barrier. In the old JMM, volatile did not prevent re-ordering. This can be important, because apart from memory barriers the only limitation imposed is that, for any particular thread, the net effect of the code is the same as it would be if the instructions were executed in precisely the order in which they appear in the source.
One use of volatile is for a shared but immutable object is recreated on the fly, with many other threads taking a reference to the object at a particular point in their execution cycle. One needs the other threads to begin using the recreated object once it is published, but does not need the additional overhead of full synchronization and it's attendant contention and cache flushing.
// Declaration
public class SharedLocation {
static public volatile SomeObject someObject=new SomeObject(); // default object
}
// Publishing code
SharedLocation.someObject=new SomeObject(...); // new object is published
// Using code
// Note: do not simply use SharedLocation.someObject.xxx(), since although
// someObject will be internally consistent for xxx(), a subsequent
// call to yyy() might be inconsistent with xxx() if the object was
// replaced in between calls.
private String getError() {
SomeObject myCopy=SharedLocation.someObject; // gets current copy
...
int cod=myCopy.getErrorCode();
String txt=myCopy.getErrorText();
return (cod+" - "+txt);
}
// And so on, with myCopy always in a consistent state within and across calls
// Eventually we will return to the code that gets the current SomeObject.
Speaking to your read-update-write question, specifically. Consider the following unsafe code:
public void updateCounter() {
if(counter==1000) { counter=0; }
else { counter++; }
}
Now, with the updateCounter() method unsynchronized, two threads may enter it at the same time. Among the many permutations of what could happen, one is that thread-1 does the test for counter==1000 and finds it true and is then suspended. Then thread-2 does the same test and also sees it true and is suspended. Then thread-1 resumes and sets counter to 0. Then thread-2 resumes and again sets counter to 0 because it missed the update from thread-1. This can also happen even if thread switching does not occur as I have described, but simply because two different cached copies of counter were present in two different CPU cores and the threads each ran on a separate core. For that matter, one thread could have counter at one value and the other could have counter at some entirely different value just because of caching.
What's important in this example is that the variable counter was read from main memory into cache, updated in cache and only written back to main memory at some indeterminate point later when a memory barrier occurred or when the cache memory was needed for something else. Making the counter volatile is insufficient for thread-safety of this code, because the test for the maximum and the assignments are discrete operations, including the increment which is a set of non-atomic read+increment+write machine instructions, something like:
MOV EAX,counter
INC EAX
MOV counter,EAX
Volatile variables are useful only when all operations performed on them are "atomic", such as my example where a reference to a fully formed object is only read or written (and, indeed, typically it's only written from a single point). Another example would be a volatile array reference backing a copy-on-write list, provided the array was only read by first taking a local copy of the reference to it.
volatile is a field modifier, while synchronized modifies code blocks and methods. So we can specify three variations of a simple accessor using those two keywords:
int i1;
int geti1() {return i1;}
volatile int i2;
int geti2() {return i2;}
int i3;
synchronized int geti3() {return i3;}
geti1() accesses the value currently stored in i1 in the current thread.
Threads can have local copies of variables, and the data does not have to be the same as the data held in other threads.In particular, another thread may have updated i1 in it's thread, but the value in the current thread could be different from that updated value. In fact Java has the idea of a "main" memory, and this is the memory that holds the current "correct" value for variables. Threads can have their own copy of data for variables, and the thread copy can be different from the "main" memory. So in fact, it is possible for the "main" memory to have a value of 1 for i1, for thread1 to have a value of 2 for i1 and for thread2 to have a value of 3 for i1 if thread1 and thread2 have both updated i1 but those updated value has not yet been propagated to "main" memory or other threads.
On the other hand, geti2() effectively accesses the value of i2 from "main" memory. A volatile variable is not allowed to have a local copy of a variable that is different from the value currently held in "main" memory. Effectively, a variable declared volatile must have it's data synchronized across all threads, so that whenever you access or update the variable in any thread, all other threads immediately see the same value. Generally volatile variables have a higher access and update overhead than "plain" variables. Generally threads are allowed to have their own copy of data is for better efficiency.
There are two differences between volitile and synchronized.
Firstly synchronized obtains and releases locks on monitors which can force only one thread at a time to execute a code block. That's the fairly well known aspect to synchronized. But synchronized also synchronizes memory. In fact synchronized synchronizes the whole of thread memory with "main" memory. So executing geti3() does the following:
The thread acquires the lock on the monitor for object this .
The thread memory flushes all its variables, i.e. it has all of its variables effectively read from "main" memory .
The code block is executed (in this case setting the return value to the current value of i3, which may have just been reset from "main" memory).
(Any changes to variables would normally now be written out to "main" memory, but for geti3() we have no changes.)
The thread releases the lock on the monitor for object this.
So where volatile only synchronizes the value of one variable between thread memory and "main" memory, synchronized synchronizes the value of all variables between thread memory and "main" memory, and locks and releases a monitor to boot. Clearly synchronized is likely to have more overhead than volatile.
http://javaexp.blogspot.com/2007/12/difference-between-volatile-and.html
There are 3 main issues with multithreading:
Race Conditions
Caching / stale memory
Compiler and CPU optimisations
volatile can solve 2 & 3, but can't solve 1. synchronized/explicit locks can solve 1, 2 & 3.
Elaboration:
Consider this thread unsafe code:
x++;
While it may look like one operation, it's actually 3: reading the current value of x from memory, adding 1 to it, and saving it back to memory. If few threads try to do it at the same time, the result of the operation is undefined. If x originally was 1, after 2 threads operating the code it may be 2 and it may be 3, depending on which thread completed which part of the operation before control was transferred to the other thread. This is a form of race condition.
Using synchronized on a block of code makes it atomic - meaning it make it as if the 3 operations happen at once, and there's no way for another thread to come in the middle and interfere. So if x was 1, and 2 threads try to preform x++ we know in the end it will be equal to 3. So it solves the race condition problem.
synchronized (this) {
x++; // no problem now
}
Marking x as volatile does not make x++; atomic, so it doesn't solve this problem.
In addition, threads have their own context - i.e. they can cache values from main memory. That means that a few threads can have copies of a variable, but they operate on their working copy without sharing the new state of the variable among other threads.
Consider that on one thread, x = 10;. And somewhat later, in another thread, x = 20;. The change in value of x might not appear in the first thread, because the other thread has saved the new value to its working memory, but hasn't copied it to the main memory. Or that it did copy it to the main memory, but the first thread hasn't updated its working copy. So if now the first thread checks if (x == 20) the answer will be false.
Marking a variable as volatile basically tells all threads to do read and write operations on main memory only. synchronized tells every thread to go update their value from main memory when they enter the block, and flush the result back to main memory when they exit the block.
Note that unlike data races, stale memory is not so easy to (re)produce, as flushes to main memory occur anyway.
The complier and CPU can (without any form of synchronization between threads) treat all code as single threaded. Meaning it can look at some code, that is very meaningful in a multithreading aspect, and treat it as if it’s single threaded, where it’s not so meaningful. So it can look at a code and decide, in sake of optimisation, to reorder it, or even remove parts of it completely, if it doesn’t know that this code is designed to work on multiple threads.
Consider the following code:
boolean b = false;
int x = 10;
void threadA() {
x = 20;
b = true;
}
void threadB() {
if (b) {
System.out.println(x);
}
}
You would think that threadB could only print 20 (or not print anything at all if threadB if-check is executed before setting b to true), as b is set to true only after x is set to 20, but the compiler/CPU might decide to reorder threadA, in that case threadB could also print 10. Marking b as volatile ensures that it won’t be reordered (or discarded in certain cases). Which mean threadB could only print 20 (or nothing at all). Marking the methods as syncrhonized will achieve the same result. Also marking a variable as volatile only ensures that it won’t get reordered, but everything before/after it can still be reordered, so synchronization can be more suited in some scenarios.
Note that before Java 5 New Memory Model, volatile didn’t solve this issue.
synchronized is method level/block level access restriction modifier. It will make sure that one thread owns the lock for critical section. Only the thread,which own a lock can enter synchronized block. If other threads are trying to access this critical section, they have to wait till current owner releases the lock.
volatile is variable access modifier which forces all threads to get latest value of the variable from main memory. No locking is required to access volatile variables. All threads can access volatile variable value at same time.
A good example to use volatile variable : Date variable.
Assume that you have made Date variable volatile. All the threads, which access this variable always get latest data from main memory so that all threads show real (actual) Date value. You don't need different threads showing different time for same variable. All threads should show right Date value.
Have a look at this article for better understanding of volatile concept.
Lawrence Dol cleary explained your read-write-update query.
Regarding your other queries
When is it more suitable to declare variables volatile than access them through synchronized?
You have to use volatile if you think all threads should get actual value of the variable in real time like the example I have explained for Date variable.
Is it a good idea to use volatile for variables that depend on input?
Answer will be same as in first query.
Refer to this article for better understanding.

Java Thread Synchronization, best concurrent utility, read operation

I have a java threads related question.
To take a very simple example, lets say I have 2 threads.
Thread A running StockReader Class instance
Thread B running StockAvgDataCollector Class instance
In Thread B, StockAvgDataCollector collects some market Data continuously, does some heavy averaging/manipulation and updates a member variable spAvgData
In Thread A StockReader has access to StockAvgDataCollector instance and its member spAvgData using getspAvgData() method.
So Thread A does READ operation only and Thread B does READ/WRITE operations.
Questions
Now, do I need synchronization or atomic functionality or locking or any concurrency related stuff in this scenario? It doesnt matter if Thread A reads an older value.
Since Thread A is only going READ and not update anything and only Thread B does any WRITE operations, will there be any deadlock scenarios?
I've pasted a paragraph below from the following link. From that paragraph, it seems like I do need to worry about some sort of locking/synchronizing.
http://java.sun.com/developer/technicalArticles/J2SE/concurrency/
Reader/Writer Locks
When using a thread to read data from an object, you do not necessarily need to prevent another thread from reading data at the same time. So long as the threads are only reading and not changing data, there is no reason why they cannot read in parallel. The J2SE 5.0 java.util.concurrent.locks package provides classes that implement this type of locking. The ReadWriteLock interface maintains a pair of associated locks, one for read-only and one for writing. The readLock() may be held simultaneously by multiple reader threads, so long as there are no writers. The writeLock() is exclusive. While in theory, it is clear that the use of reader/writer locks to increase concurrency leads to performance improvements over using a mutual exclusion lock. However, this performance improvement will only be fully realized on a multi-processor and the frequency that the data is read compared to being modified as well as the duration of the read and write operations.
Which concurrent utility would be less expensive and suitable in my example?
java.util.concurrent.atomic ?
java.util.concurrent.locks ?
java.util.concurrent.ConcurrentLinkedQueue ? - In this case StockAvgDataCollector will add and StockReader will remove. No getspAvgData() method will be exposed.
Thanks
Amit
Well, the whole ReadWriteLock thing really makes sense when you have many readers and at least one writer... So you guarantee liveliness (you won't be blocking any reader threads if no one other thread is writing). However, you have only two threads.
If you don't mind thread B reading an old (but not corrupted) value of spAvgData, then I would go for an AtomicDouble (or AtomicReference, depending on what spAvgData's datatype).
So the code would look like this
public class A extends Thread {
// spAvgData
private final AtomicDouble spAvgData = new AtomicDouble(someDefaultValue);
public void run() {
while (compute) {
// do intensive work
// ...
// done with work, update spAvgData
spAvgData.set(resultOfComputation);
}
}
public double getSpAvgData() {
return spAvgData.get();
}
}
// --------------
public class B {
public void someMethod() {
A a = new A();
// after A being created, spAvgData contains a valid value (at least the default)
a.start();
while(read) {
// loll around
a.getSpAvgData();
}
}
}
Yes, synchronization is important and you need to consider two parameters: visibility of the spAvgData variable and atomicity of its update. In order to guarantee visibility of the spAvgData variable in thread B by thread A, the variable can be declared volatile or as an AtomicReference. Also you need to guard that the action of the update is atomic in case there are more invariants involved or the update action is a compound action, using synchronization and locking. If only thread B is updating that variable then you don't need synchronization and visibility should be enough for thread A to read the most up-to-date value of the variable.
If you don't mind that Thread A can read complete nonsense (including partially updated data) then no, you don't need any synchronisation. However, I suspect that you should mind.
If you just use a single mutex, or ReentrantReadWriteLock and don't suspend or sleep without timeout while holding locks then there will be no deadlock. If you do perform unsafe thread operations, or try to roll your own synchronisation solution, then you will need to worry about it.
If you use a blocking queue then you will also need a constantly-running ingestion loop in StockReader. ReadWriteLock is still of benefit on a single core processor - the issues are the same whether the threads are physically running at the same time, or just interleaved by context switches.
If you don't use at least some form of synchronisation (e.g. a volatile) then your reader may never see any change at all.

Are static variables shared between threads?

My teacher in an upper level Java class on threading said something that I wasn't sure of.
He stated that the following code would not necessarily update the ready variable. According to him, the two threads don't necessarily share the static variable, specifically in the case when each thread (main thread versus ReaderThread) is running on its own processor and therefore doesn't share the same registers/cache/etc and one CPU won't update the other.
Essentially, he said it is possible that ready is updated in the main thread, but NOT in the ReaderThread, so that ReaderThread will loop infinitely.
He also claimed it was possible for the program to print 0 or 42. I understand how 42 could be printed, but not 0. He mentioned this would be the case when the number variable is set to the default value.
I thought perhaps it is not guaranteed that the static variable is updated between the threads, but this strikes me as very odd for Java. Does making ready volatile correct this problem?
He showed this code:
public class NoVisibility {
private static boolean ready;
private static int number;
private static class ReaderThread extends Thread {
public void run() {
while (!ready) Thread.yield();
System.out.println(number);
}
}
public static void main(String[] args) {
new ReaderThread().start();
number = 42;
ready = true;
}
}
There isn't anything special about static variables when it comes to visibility. If they are accessible any thread can get at them, so you're more likely to see concurrency problems because they're more exposed.
There is a visibility issue imposed by the JVM's memory model. Here's an article talking about the memory model and how writes become visible to threads. You can't count on changes one thread makes becoming visible to other threads in a timely manner (actually the JVM has no obligation to make those changes visible to you at all, in any time frame), unless you establish a happens-before relationship.
Here's a quote from that link (supplied in the comment by Jed Wesley-Smith):
Chapter 17 of the Java Language Specification defines the happens-before relation on memory operations such as reads and writes of shared variables. The results of a write by one thread are guaranteed to be visible to a read by another thread only if the write operation happens-before the read operation. The synchronized and volatile constructs, as well as the Thread.start() and Thread.join() methods, can form happens-before relationships. In particular:
Each action in a thread happens-before every action in that thread that comes later in the program's order.
An unlock (synchronized block or method exit) of a monitor happens-before every subsequent lock (synchronized block or method entry) of that same monitor. And because the happens-before relation is transitive, all actions of a thread prior to unlocking happen-before all actions subsequent to any thread locking that monitor.
A write to a volatile field happens-before every subsequent read of that same field. Writes and reads of volatile fields have similar memory consistency effects as entering and exiting monitors, but do not entail mutual exclusion locking.
A call to start on a thread happens-before any action in the started thread.
All actions in a thread happen-before any other thread successfully returns from a join on that thread.
He was talking about visibility and not to be taken too literally.
Static variables are indeed shared between threads, but the changes made in one thread may not be visible to another thread immediately, making it seem like there are two copies of the variable.
This article presents a view that is consistent with how he presented the info:
http://jeremymanson.blogspot.com/2008/11/what-volatile-means-in-java.html
First, you have to understand a little something about the Java memory model. I've struggled a bit over the years to explain it briefly and well. As of today, the best way I can think of to describe it is if you imagine it this way:
Each thread in Java takes place in a separate memory space (this is clearly untrue, so bear with me on this one).
You need to use special mechanisms to guarantee that communication happens between these threads, as you would on a message passing system.
Memory writes that happen in one thread can "leak through" and be seen by another thread, but this is by no means guaranteed. Without explicit communication, you can't guarantee which writes get seen by other threads, or even the order in which they get seen.
...
But again, this is simply a mental model to think about threading and volatile, not literally how the JVM works.
Basically it's true, but actually the problem is more complex. Visibility of shared data can be affected not only by CPU caches, but also by out-of-order execution of instructions.
Therefore Java defines a Memory Model, that states under which circumstances threads can see consistent state of the shared data.
In your particular case, adding volatile guarantees visibility.
They are "shared" of course in the sense that they both refer to the same variable, but they don't necessarily see each other's updates. This is true for any variable, not just static.
And in theory, writes made by another thread can appear to be in a different order, unless the variables are declared volatile or the writes are explicitly synchronized.
Within a single classloader, static fields are always shared. To explicitly scope data to threads, you'd want to use a facility like ThreadLocal.
When you initialize static primitive type variable java default assigns a value for static variables
public static int i ;
when you define the variable like this the default value of i = 0;
thats why there is a possibility to get you 0.
then the main thread updates the value of boolean ready to true. since ready is a static variable , main thread and the other thread reference to the same memory address so the ready variable change. so the secondary thread get out from while loop and print value.
when printing the value initialized value of number is 0. if the thread process has passed while loop before main thread update number variable. then there is a possibility to print 0
#dontocsata
you can go back to your teacher and school him a little :)
few notes from the real world and regardless what you see or be told.
Please NOTE, the words below are regarding this particular case in the exact order shown.
The following 2 variable will reside on the same cache line under virtually any know architecture.
private static boolean ready;
private static int number;
Thread.exit (main thread) is guaranteed to exit and exit is guaranteed to cause a memory fence, due to the thread group thread removal (and many other issues). (it's a synchronized call, and I see no single way to be implemented w/o the sync part since the ThreadGroup must terminate as well if no daemon threads are left, etc).
The started thread ReaderThread is going to keep the process alive since it is not a daemon one!
Thus ready and number will be flushed together (or the number before if a context switch occurs) and there is no real reason for reordering in this case at least I can't even think of one.
You will need something truly weird to see anything but 42. Again I do presume both static variables will be in the same cache line. I just can't imagine a cache line 4 bytes long OR a JVM that will not assign them in a continuous area (cache line).

Difference between volatile and synchronized in Java

I am wondering at the difference between declaring a variable as volatile and always accessing the variable in a synchronized(this) block in Java?
According to this article http://www.javamex.com/tutorials/synchronization_volatile.shtml there is a lot to be said and there are many differences but also some similarities.
I am particularly interested in this piece of info:
...
access to a volatile variable never has the potential to block: we're only ever doing a simple read or write, so unlike a synchronized block we will never hold on to any lock;
because accessing a volatile variable never holds a lock, it is not suitable for cases where we want to read-update-write as an atomic operation (unless we're prepared to "miss an update");
What do they mean by read-update-write? Isn't a write also an update or do they simply mean that the update is a write that depends on the read?
Most of all, when is it more suitable to declare variables volatile rather than access them through a synchronized block? Is it a good idea to use volatile for variables that depend on input? For instance, there is a variable called render that is read through the rendering loop and set by a keypress event?
It's important to understand that there are two aspects to thread safety.
execution control, and
memory visibility
The first has to do with controlling when code executes (including the order in which instructions are executed) and whether it can execute concurrently, and the second to do with when the effects in memory of what has been done are visible to other threads. Because each CPU has several levels of cache between it and main memory, threads running on different CPUs or cores can see "memory" differently at any given moment in time because threads are permitted to obtain and work on private copies of main memory.
Using synchronized prevents any other thread from obtaining the monitor (or lock) for the same object, thereby preventing all code blocks protected by synchronization on the same object from executing concurrently. Synchronization also creates a "happens-before" memory barrier, causing a memory visibility constraint such that anything done up to the point some thread releases a lock appears to another thread subsequently acquiring the same lock to have happened before it acquired the lock. In practical terms, on current hardware, this typically causes flushing of the CPU caches when a monitor is acquired and writes to main memory when it is released, both of which are (relatively) expensive.
Using volatile, on the other hand, forces all accesses (read or write) to the volatile variable to occur to main memory, effectively keeping the volatile variable out of CPU caches. This can be useful for some actions where it is simply required that visibility of the variable be correct and order of accesses is not important. Using volatile also changes treatment of long and double to require accesses to them to be atomic; on some (older) hardware this might require locks, though not on modern 64 bit hardware. Under the new (JSR-133) memory model for Java 5+, the semantics of volatile have been strengthened to be almost as strong as synchronized with respect to memory visibility and instruction ordering (see http://www.cs.umd.edu/users/pugh/java/memoryModel/jsr-133-faq.html#volatile). For the purposes of visibility, each access to a volatile field acts like half a synchronization.
Under the new memory model, it is still true that volatile variables cannot be reordered with each other. The difference is that it is now no longer so easy to reorder normal field accesses around them. Writing to a volatile field has the same memory effect as a monitor release, and reading from a volatile field has the same memory effect as a monitor acquire. In effect, because the new memory model places stricter constraints on reordering of volatile field accesses with other field accesses, volatile or not, anything that was visible to thread A when it writes to volatile field f becomes visible to thread B when it reads f.
-- JSR 133 (Java Memory Model) FAQ
So, now both forms of memory barrier (under the current JMM) cause an instruction re-ordering barrier which prevents the compiler or run-time from re-ordering instructions across the barrier. In the old JMM, volatile did not prevent re-ordering. This can be important, because apart from memory barriers the only limitation imposed is that, for any particular thread, the net effect of the code is the same as it would be if the instructions were executed in precisely the order in which they appear in the source.
One use of volatile is for a shared but immutable object is recreated on the fly, with many other threads taking a reference to the object at a particular point in their execution cycle. One needs the other threads to begin using the recreated object once it is published, but does not need the additional overhead of full synchronization and it's attendant contention and cache flushing.
// Declaration
public class SharedLocation {
static public volatile SomeObject someObject=new SomeObject(); // default object
}
// Publishing code
SharedLocation.someObject=new SomeObject(...); // new object is published
// Using code
// Note: do not simply use SharedLocation.someObject.xxx(), since although
// someObject will be internally consistent for xxx(), a subsequent
// call to yyy() might be inconsistent with xxx() if the object was
// replaced in between calls.
private String getError() {
SomeObject myCopy=SharedLocation.someObject; // gets current copy
...
int cod=myCopy.getErrorCode();
String txt=myCopy.getErrorText();
return (cod+" - "+txt);
}
// And so on, with myCopy always in a consistent state within and across calls
// Eventually we will return to the code that gets the current SomeObject.
Speaking to your read-update-write question, specifically. Consider the following unsafe code:
public void updateCounter() {
if(counter==1000) { counter=0; }
else { counter++; }
}
Now, with the updateCounter() method unsynchronized, two threads may enter it at the same time. Among the many permutations of what could happen, one is that thread-1 does the test for counter==1000 and finds it true and is then suspended. Then thread-2 does the same test and also sees it true and is suspended. Then thread-1 resumes and sets counter to 0. Then thread-2 resumes and again sets counter to 0 because it missed the update from thread-1. This can also happen even if thread switching does not occur as I have described, but simply because two different cached copies of counter were present in two different CPU cores and the threads each ran on a separate core. For that matter, one thread could have counter at one value and the other could have counter at some entirely different value just because of caching.
What's important in this example is that the variable counter was read from main memory into cache, updated in cache and only written back to main memory at some indeterminate point later when a memory barrier occurred or when the cache memory was needed for something else. Making the counter volatile is insufficient for thread-safety of this code, because the test for the maximum and the assignments are discrete operations, including the increment which is a set of non-atomic read+increment+write machine instructions, something like:
MOV EAX,counter
INC EAX
MOV counter,EAX
Volatile variables are useful only when all operations performed on them are "atomic", such as my example where a reference to a fully formed object is only read or written (and, indeed, typically it's only written from a single point). Another example would be a volatile array reference backing a copy-on-write list, provided the array was only read by first taking a local copy of the reference to it.
volatile is a field modifier, while synchronized modifies code blocks and methods. So we can specify three variations of a simple accessor using those two keywords:
int i1;
int geti1() {return i1;}
volatile int i2;
int geti2() {return i2;}
int i3;
synchronized int geti3() {return i3;}
geti1() accesses the value currently stored in i1 in the current thread.
Threads can have local copies of variables, and the data does not have to be the same as the data held in other threads.In particular, another thread may have updated i1 in it's thread, but the value in the current thread could be different from that updated value. In fact Java has the idea of a "main" memory, and this is the memory that holds the current "correct" value for variables. Threads can have their own copy of data for variables, and the thread copy can be different from the "main" memory. So in fact, it is possible for the "main" memory to have a value of 1 for i1, for thread1 to have a value of 2 for i1 and for thread2 to have a value of 3 for i1 if thread1 and thread2 have both updated i1 but those updated value has not yet been propagated to "main" memory or other threads.
On the other hand, geti2() effectively accesses the value of i2 from "main" memory. A volatile variable is not allowed to have a local copy of a variable that is different from the value currently held in "main" memory. Effectively, a variable declared volatile must have it's data synchronized across all threads, so that whenever you access or update the variable in any thread, all other threads immediately see the same value. Generally volatile variables have a higher access and update overhead than "plain" variables. Generally threads are allowed to have their own copy of data is for better efficiency.
There are two differences between volitile and synchronized.
Firstly synchronized obtains and releases locks on monitors which can force only one thread at a time to execute a code block. That's the fairly well known aspect to synchronized. But synchronized also synchronizes memory. In fact synchronized synchronizes the whole of thread memory with "main" memory. So executing geti3() does the following:
The thread acquires the lock on the monitor for object this .
The thread memory flushes all its variables, i.e. it has all of its variables effectively read from "main" memory .
The code block is executed (in this case setting the return value to the current value of i3, which may have just been reset from "main" memory).
(Any changes to variables would normally now be written out to "main" memory, but for geti3() we have no changes.)
The thread releases the lock on the monitor for object this.
So where volatile only synchronizes the value of one variable between thread memory and "main" memory, synchronized synchronizes the value of all variables between thread memory and "main" memory, and locks and releases a monitor to boot. Clearly synchronized is likely to have more overhead than volatile.
http://javaexp.blogspot.com/2007/12/difference-between-volatile-and.html
There are 3 main issues with multithreading:
Race Conditions
Caching / stale memory
Compiler and CPU optimisations
volatile can solve 2 & 3, but can't solve 1. synchronized/explicit locks can solve 1, 2 & 3.
Elaboration:
Consider this thread unsafe code:
x++;
While it may look like one operation, it's actually 3: reading the current value of x from memory, adding 1 to it, and saving it back to memory. If few threads try to do it at the same time, the result of the operation is undefined. If x originally was 1, after 2 threads operating the code it may be 2 and it may be 3, depending on which thread completed which part of the operation before control was transferred to the other thread. This is a form of race condition.
Using synchronized on a block of code makes it atomic - meaning it make it as if the 3 operations happen at once, and there's no way for another thread to come in the middle and interfere. So if x was 1, and 2 threads try to preform x++ we know in the end it will be equal to 3. So it solves the race condition problem.
synchronized (this) {
x++; // no problem now
}
Marking x as volatile does not make x++; atomic, so it doesn't solve this problem.
In addition, threads have their own context - i.e. they can cache values from main memory. That means that a few threads can have copies of a variable, but they operate on their working copy without sharing the new state of the variable among other threads.
Consider that on one thread, x = 10;. And somewhat later, in another thread, x = 20;. The change in value of x might not appear in the first thread, because the other thread has saved the new value to its working memory, but hasn't copied it to the main memory. Or that it did copy it to the main memory, but the first thread hasn't updated its working copy. So if now the first thread checks if (x == 20) the answer will be false.
Marking a variable as volatile basically tells all threads to do read and write operations on main memory only. synchronized tells every thread to go update their value from main memory when they enter the block, and flush the result back to main memory when they exit the block.
Note that unlike data races, stale memory is not so easy to (re)produce, as flushes to main memory occur anyway.
The complier and CPU can (without any form of synchronization between threads) treat all code as single threaded. Meaning it can look at some code, that is very meaningful in a multithreading aspect, and treat it as if it’s single threaded, where it’s not so meaningful. So it can look at a code and decide, in sake of optimisation, to reorder it, or even remove parts of it completely, if it doesn’t know that this code is designed to work on multiple threads.
Consider the following code:
boolean b = false;
int x = 10;
void threadA() {
x = 20;
b = true;
}
void threadB() {
if (b) {
System.out.println(x);
}
}
You would think that threadB could only print 20 (or not print anything at all if threadB if-check is executed before setting b to true), as b is set to true only after x is set to 20, but the compiler/CPU might decide to reorder threadA, in that case threadB could also print 10. Marking b as volatile ensures that it won’t be reordered (or discarded in certain cases). Which mean threadB could only print 20 (or nothing at all). Marking the methods as syncrhonized will achieve the same result. Also marking a variable as volatile only ensures that it won’t get reordered, but everything before/after it can still be reordered, so synchronization can be more suited in some scenarios.
Note that before Java 5 New Memory Model, volatile didn’t solve this issue.
synchronized is method level/block level access restriction modifier. It will make sure that one thread owns the lock for critical section. Only the thread,which own a lock can enter synchronized block. If other threads are trying to access this critical section, they have to wait till current owner releases the lock.
volatile is variable access modifier which forces all threads to get latest value of the variable from main memory. No locking is required to access volatile variables. All threads can access volatile variable value at same time.
A good example to use volatile variable : Date variable.
Assume that you have made Date variable volatile. All the threads, which access this variable always get latest data from main memory so that all threads show real (actual) Date value. You don't need different threads showing different time for same variable. All threads should show right Date value.
Have a look at this article for better understanding of volatile concept.
Lawrence Dol cleary explained your read-write-update query.
Regarding your other queries
When is it more suitable to declare variables volatile than access them through synchronized?
You have to use volatile if you think all threads should get actual value of the variable in real time like the example I have explained for Date variable.
Is it a good idea to use volatile for variables that depend on input?
Answer will be same as in first query.
Refer to this article for better understanding.

Categories

Resources