As far as I know volatile write happens-before volatile read, so we always will see the freshest data in volatile variable. My question basically concerns the term happens-before and where does it take place? I wrote a piece of code to clarify my question.
class Test {
volatile int a;
public static void main(String ... args) {
final Test t = new Test();
new Thread(new Runnable(){
#Override
public void run() {
Thread.sleep(3000);
t.a = 10;
}
}).start();
new Thread(new Runnable(){
#Override
public void run() {
System.out.println("Value " + t.a);
}
}).start();
}
}
(try catch block is omitted for clarity)
In this case I always see the value 0 to be printed on console. Without Thread.sleep(3000); i always see value 10. Is this a case of happens-before relationship or it prints 'value 10' because thread 1 starts a bit earlier thread 2?
It would be great to see the example where the behaviour of code with and without volatile variable differs in every program start, because the result of code above depends only(at least in my case) on the order of threads and on thread sleeping.
You see the value 0 because the read is executed before the write. And you see the value 10 because the write is executed before the read.
If you want to have a test with more unpredictable output, you should have both of your threads await a CountDownLatch, to make them start concurrently:
final CountDownLatch latch = new CountDownLatch(1);
new Thread(new Runnable(){
#Override
public void run() {
try {
latch.await();
t.a = 10;
}
catch (InterruptedException e) {
// end the thread
}
}
}).start();
new Thread(new Runnable(){
#Override
public void run() {
try {
latch.await();
System.out.println("Value " + t.a);
}
catch (InterruptedException e) {
// end the thread
}
}
}).start();
Thread.sleep(321); // go
latch.countDown();
The happens-before really has to do with a write happens before any subsequent read. If the write has not occurred yet there really is no relationship. Since the write-thread is sleeping the read is executed before the write occurs.
To observe the relationship in action you can have two variables one that is volatile and one that is not. According to the JMM it says the write to a non-volatile variable before a volatile write happens before the volatile read.
For instance
volatile int a = 0;
int b = 0;
Thread 1:
b = 10;
a = 1;
Thread 2:
while(a != 1);
if(b != 10)
throw new IllegalStateException();
The Java Memory Model says that b should always equal 10 because the non-volatile store occurs before the volatile store. And all writes that occur in one thread before a volatile store happen-before all subsequent volatile loads.
I've re-phrased (changes in bold fonts) the happens-before rule mentioned in the first sentence of your question as below so that it could be understood better -
"write of the value of a volatile variable to the main memory happens-before any subsequent read of that varible from main memory".
Also it is important to note that volatile writes/reads always
happen to/from the main memory and NOT to/from any local memory
resources like registers, processor caches etc.
The practical implication of the above happens-before rule is that all the threads that share a volatile variable will always see consistent value of that variable. No two threads see different values of that variable at any given point of time.
On the contrary, all the threads that share a non-volatile variable may see different values at any given point of time unless it is not synchronized by any other kind of synchronization mechanisms such as synchronized block/method, final keyword etc.
Now coming back to your question on this happens-before rule, i think u've slightly misunderstood that rule. The rule does not dictate that a write code should always happen (execute) before a read code. Rather it dictates that if a write code (volatile variable write) were to be executed in one thread before a read code in another thread then the effect of the write code should have happened in the main memory before the read code is executed so that the read code can see the latest value.
In the absence of volatile (or any other synchronization mechanisms), this happens-before is not mandatory, and hence a reader thread might see a stale value of non-volatile variable even though it has been recently written by a different writer thread. Because the writer thread can store the value in its local copy and need not have flushed the value to the main memory.
Hope the above explanation is clear :)
don't stick to the term 'happens-before'. it is a relation between events, used by jvm during R/W operations scheduling. at this stage it won't help you understand the volatile. the point is: jvm orders all R/W operations. jvm can order however it wants (of course obeying to all synchronize, lock, wait etc).
and now: if variable is volatile then any read operation will see the result of latest write operation. if variable is not volatile then it is not guaranteed (in different threads). that's all
piotrek is right, here is the test:
class Test {
volatile int a = 0;
public static void main(String ... args) {
final Test t = new Test();
new Thread(new Runnable(){
#Override
public void run() {
try {
Thread.sleep(3000);
} catch (Exception e) {}
t.a = 10;
System.out.println("now t.a == 10");
}
}).start();
new Thread(new Runnable(){
#Override
public void run() {
while(t.a == 0) {}
System.out.println("Loop done: " + t.a);
}
}).start();
}
}
with volatile: it will always end
without volatile: it will never end
From wiki:
In Java specifically, a happens-before relationship is a guarantee that memory written to by statement A is visible to statement B, that is, that statement A completes its write before statement B starts its read.
So if thread A write t.a with value 10 and thread B tries to read t.a some later, happens-before relationship guarantees that thread B must read value 10 written by thread A, not any other value. It's natural, just like Alice buys milk and put them into fridge then Bob opens fridge and sees the milk. However, when computer is running, memory access usually doesn't access memory directly, that's too slow. Instead, software get the data from register or cache to save time. It loads data from memory only when cache miss happens. That the problem happens.
Let's see the code in the question:
class Test {
volatile int a;
public static void main(String ... args) {
final Test t = new Test();
new Thread(new Runnable(){ //thread A
#Override
public void run() {
Thread.sleep(3000);
t.a = 10;
}
}).start();
new Thread(new Runnable(){ //thread B
#Override
public void run() {
System.out.println("Value " + t.a);
}
}).start();
}
}
Thread A writes 10 into value t.a and thread B tries to read it out. Suppose thread A writes before thread B reads, then when thread B reads it will load the value from the memory because it doesn't cache the value in register or cache so it always get 10 written by thread A. And if thread A writes after thread B reads, thread B reads initial value (0). So this example doesn't show how volatile works and the difference. But if we change the code like this:
class Test {
volatile int a;
public static void main(String ... args) {
final Test t = new Test();
new Thread(new Runnable(){ //thread A
#Override
public void run() {
Thread.sleep(3000);
t.a = 10;
}
}).start();
new Thread(new Runnable(){ //thread B
#Override
public void run() {
while (1) {
System.out.println("Value " + t.a);
}
}
}).start();
}
}
Without volatile, the print value should always be initial value (0) even some read happens after thread A writes 10 into t.a, which violate the happen-before relationship. The reason is compiler optimizes the code and save the t.a into register and every time it will use the register value instead of reading from cache memory, of course which much faster. But it also cause the happen-before relationship violation problem because thread B can't get the right value after others update it.
In the above example, volatile write happens-before volatile read means that with volatile thread B will get the right value of t.a once after thread A update it. Compiler will guarantee every time thread B reads t.a, it must read from cache or memory instead of just using register's stale value.
Related
I am totally puzzled with the two samples.
public class VTest {
private static /*volatile*/ boolean leap = true;
public static void main(String[] args) throws InterruptedException {
Thread t2 = new Thread(new Runnable() {
#Override
public void run() {
while (leap) {
}
}
});
t2.start();
Thread.sleep(3000);
leap = false;
}
}
In this case, t2 is not able to stop, as leap was stored locally so that t2 can't access the leap updated in main thread.
public class VTest2 {
private static int m = 0;
public static void main(String[] args) throws InterruptedException {
Thread t2 = new Thread(new Runnable() {
#Override
public void run() {
for (int i = 0; i < 10000; ++i) ++m;
}
});
t2.start();
for (int i = 0; i < 10000; ++i) ++m;
Thread.sleep(3000);
System.out.println(m);
}
}
But, in this case, the m is always be 20000, why isn't 10000?
Any answer will be appreciated.
It's not really a matter of "when". Because of the way that m is declared, the two threads have no reason to believe that it needs to consider the value in main memory.
Consider that ++m is not an atomic operation, but is rather:
A read
An increment
A write
Because the thread doesn't know it needs to read from or flush to main memory, there is no guarantee as to how it is executed:
Perhaps it reads from main memory each time, and flushes to main memory each time
Perhaps it reads from main memory just once, and doesn't flush to main memory when it writes
Perhaps it reads from/writes to main memory on some iterations of the loop
(...many other ways)
So, essentially, the answer is that there is no guarantee that the value is read from or written to main memory, ever.
If you declare m as volatile, that gives you some guarantees: that m is definitely read from main memory, and definitely flushed to main memory. However, because ++m isn't atomic, there is no guarantee that you get 20000 at the end (it's possible it could be 2, at worst), because the work of the two threads can intersperse (e.g. both threads read the same value of m, increment it, and both write back the same value m+1).
To do this correctly, you need to ensure that:
++m is executed atomically
The value is guaranteed to be visible.
The easiest way of doing this would be to use an AtomicInteger instead; however, you could mutually synchronize the increments:
synchronized (VTest2.class) {
++m;
}
You then also need to synchronize the final read, in order to ensure you are definitely seeing the last value written by t2:
synchronized (VTest2.class) {
System.out.println(m);
}
In this case, t2 is not able to stop, as leap was stored locally so that t2 can't access the leap updated in main thread.
That's not really the case: the leap variable was not stored "locally" by the thread. It's still a shared static variable. However, because it is not marked as volatile, and there is no synchronization happening whatsoever, the JVM (the JIT in particular) is free to do optimization to avoid loading it. I believe in this case it is removing the check on the variable.
Note: The second code incrementing m is not thread-safe: try increasing the loop to millions to test that, it will almost never match the expected sum.
I have a use case with many writer threads and a single reader thread. The data being written is an event counter which is being read by a display thread.
The counter only ever increases and the display is intended for humans, so the exact point-in-time value is not critical. For this purpose, I would consider a solution to be correct as long as:
The value seen by the reader thread never decreases.
Reads are eventually consistent. After a certain amount of time without any writes, all reads will return the exact value.
Assuming writers are properly synchronized with each other, is it necessary to synchronize the reader thread with the writers in order to guarantee correctness, as defined above?
A simplified example. Would this be correct, as defined above?
public class Eventual {
private static class Counter {
private int count = 0;
private Lock writeLock = new ReentrantLock();
// Unsynchronized reads
public int getCount() {
return count;
}
// Synchronized writes
public void increment() {
writeLock.lock();
try {
count++;
} finally {
writeLock.unlock();
}
}
}
public static void main(String[] args) {
List<Thread> contentiousThreads = new ArrayList<>();
final Counter sharedCounter = new Counter();
// 5 synchronized writer threads
for(int i = 0; i < 5; ++i) {
contentiousThreads.add(new Thread(new Runnable(){
#Override
public void run() {
for(int i = 0; i < 20_000; ++i) {
sharedCounter.increment();
safeSleep(1);
}
}
}));
}
// 1 unsynchronized reader thread
contentiousThreads.add(new Thread(new Runnable(){
#Override
public void run() {
for(int i = 0; i < 30; ++i) {
// This value should:
// +Never decrease
// +Reach 100,000 if we are eventually consistent.
System.out.println("Count: " + sharedCounter.getCount());
safeSleep(1000);
}
}
}));
contentiousThreads.stream().forEach(t -> t.start());
// Just cleaning up...
// For the question, assume readers/writers run indefinitely
try {
for(Thread t : contentiousThreads) {
t.join();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private static void safeSleep(int ms) {
try {
Thread.sleep(ms);
} catch (InterruptedException e) {
//Don't care about error handling for now.
}
}
}
There is no guarantee that the readers would ever see an update to the count. A simple fix is to make count volatile.
As noted in another answer, in your current example, the "Final Count" will be correct because the main thread is joining the writer threads (thus establishing a happens-before relationship). however, your reader thread is never guaranteed to see any update to the count.
JTahlborn is correct, +1 from me. I was rushing and misread the question, I was assuming wrongly that the reader thread was the main thread.
The main thread can display the final count correctly due to the happens-before relationship:
All actions in a thread happen-before any other thread successfully returns from a join on that thread.
Once the main thread has joined to all the writers then the counter's updated value is visible. However, there is no happens-before relationship forcing the reader's view to get updated, you are at the mercy of the JVM implementation. There is no promise in the JLS about values getting visible if enough time passes, it is left open to the implementation. The counter value could get cached and the reader could possibly not see any updates whatsoever.
Testing this on one platform gives no assurance of what other platforms will do, so don't think this is OK just because the test passes on your PC. How many of us develop on the same platform we deploy to?
Using volatile on the counter or using AtomicInteger would be good fixes. Using AtomicInteger would allow removing the locks from the writer thread. Using volatile without locking would be OK only in a case where there is just one writer, when two or more writers are present then ++ or += not being threadsafe will be an issue. Using an Atomic class is a better choice.
(Btw eating the InterruptedException isn't "safe", it just makes the thread unresponsive to interruption, which happens when your program asks the thread to finish early.)
I was expecting this code to be thread safe. I ran it a few times, but got different results. However, if I uncomment the sleep(1000) part, it prints 10000 every time (at least from the results from my test runs).
So what's wrong? Could it be something to do with thread.join()?
public class Test implements Runnable{
private int x;
public synchronized void run(){
x++;
}
public static void main(String args[]){
Test test = new Test();
Thread thread = null;
for (int i = 0; i < 10000; i++) {
thread = new Thread(test);
try {
thread.join();
} catch (InterruptedException e) {}
thread.start();
}
// try {
// Thread.sleep(1000);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
System.out.println(test.x);
}
}
edit: oops, my bad. I misunderstood how Thread#join functions. And synchronizing on run() method is a bad idea.
thread.join() should be called after thread.start().
join() means "block until the thread finishes". That only makes sense after the thread has started.
Presumably your Thread.sleep() call actually waits long enough for all the threads (that you effectively didn't join) to finish. Without it, the threads might not all have finished when you print out the value of x.
There are two problems here:
a race condition where the main thread finishes before all the worker threads.
a memory visibility issue where the main thread is not guaranteed to see the updated value of x.
Thread#join is implemented using Object#wait. The condition variable used is the alive flag on the Thread:
groovy:000> new Thread().isAlive()
===> false
Thread.join is checking the alive flag before the thread has started, so isAlive returns false and join returns before the thread can start. The counter still gets incremented eventually, but since the join doesn't happen for that thread then the main thread may be printing out the results for x before all the threads can execute.
Adding the sleep gives all the threads enough time to finish up that x is what you expect by the time that the main thread prints it out.
In addition to the race condition, there is a memory visibility issue since the main thread is accessing x directly and is not using the same lock as the other threads. You should add an accessor to your Runnable using the synchronized keyword:
public class Test implements Runnable{
private int x;
public synchronized void run(){
x++;
}
public synchronized int getX() {
return x;
}
and change the main method to use the accessor:
System.out.println(test.getX());
Memory visibility issues may not be apparent since they depend on how aggressive the JVM is about caching and optimizing. If your code runs against a different JVM implementation in production, and you don't adequately guard against these issues, you may see errors there that you can't reproduce locally on a PC.
Using AtomicInteger would simplify this code and allow solving the memory visibility problem while removing synchronization.
You don't add synchronized to the run method. Each thread gets its own.
You have to synchronize the mutable, shared data. In your case, that's the integer x. You can synchronize get/set or use AtomicInteger.
I am unable to understand that if my variable is both volatile and static then why threads are not reflecting the common shared value in the output
Output of last few lines is :
Thread is running
4998Thread-0
Thread is running
4999Thread-0
Thread is running
4899Thread-1
Thread is running
public class Test implements Runnable{
volatile static int i=0;
#Override
public void run() {
for(;i<5000;i++)
{ try {
Thread t = Thread.currentThread();
String name = t.getName();
// Thread.sleep(10);
System.out.println(i+name);
} catch (Exception ex) {
ex.printStackTrace();
}
System.out.println("Thread is running");
}}
public static void main(String[] args) {
Test t=new Test();
Thread t1=new Thread(t);
Thread t2=new Thread(t);
t1.start();
// t.run();
t2.start();
}
}
You can't use a compound (multi step) operation like i++ on a volatile variable.
You can have both threads retrieve the value, increase it, and write it back resulting in one lost increment (as you see in your example).
Volatile ensures that changes to the variable are visible to other threads. But it does not ensure synchronization.
From one execution of your program I get this output :
Thread is running
3474Thread-1
Thread is running
3475Thread-0
Thread is running
3477Thread-0
(.... many lines where i goes from 3478 to 4998, with Thread-0 always being the one running...)
Thread is running
4999Thread-0
Thread is running
3476Thread-1
Thread is running
This happens because threads get slices of processor time to be run and their execution can be paused and resumed at any point.
Here Thread-1 is executing line "System.out.println(i+name);" with i having a value of 3476. i+name is evaluated to "3476Thread-1" but just then the Thread-1 execution stops and instead Thread-0 gets its time slice. Thread-0 executes till finalization. And then Thread-1 gets again to execute. We have left it after i+name had been evaluated to "3476Thread-1" and before the call to println. The call is now completed and printed, hence you see "3476Thread-1" at then end. i has been increased to 5000 by Thread-0 but that does not change the result of the evaluation of i+name which was done before all those increases.
The problem is that i++ and i+name are different instructions and thread execution can be paused and resumed between them. To ensure that you get a secuential output you need to ensure than there is no interruption between i++ and i+name. That is, you need to make that set of instructions atomic.
public class Test implements Runnable{
static Object lock = new Object();
volatile static int i=0;
#Override
public void run() {
for(;;)
{
try {
Thread t = Thread.currentThread();
String name = t.getName();
synchronized( lock )
{
if ( i>=5000 )
break;
i++;
System.out.println(i+name);
}
// Thread.sleep(10);
} catch (Exception ex) {
ex.printStackTrace();
System.out.println("Thread is running");
}
} }
public static void main(String[] args) {
Test t=new Test();
Thread t1=new Thread(t);
Thread t2=new Thread(t);
t1.start();
// t.run();
t2.start();
}
}
In that program, if Thread-1 gets paused between i++ and i+name it will be inside the a critical section controlled by synchronized(lock). When Thread-0 gets to execute it will reach the synchronized(lock) instruction and will have to stop executing until Thread-1 resumes and gets out of that block. Because the JLS ensures that :
The synchronized statement (ยง14.19) computes a reference to an object;
it then attempts to perform a lock action on that object's monitor and
does not proceed further until the lock action has successfully
completed. After the lock action has been performed, the body of the
synchronized statement is executed. If execution of the body is ever
completed, either normally or abruptly, an unlock action is
automatically performed on that same monitor.
Here's a code snippet I learned usage of volatile keyword from:
import java.util.concurrent.TimeUnit;
public class VolatileDemo {
private volatile static boolean stop; //remove volatile keyword to see the difference
private static int i = 0;
public static void main(String[] args) throws InterruptedException {
Thread otherThread = new Thread(new Runnable() {
public void run() {
while (!stop)
i++;
}
});
otherThread.start();
TimeUnit.SECONDS.sleep(1);
stop = true;// main thread stops here and should stop otherThread as well
}
}
If you want to observe what volatile does, try to remove it and then follow the execution, this should be obvious after you run those two versions, but basically keyword here prevents java compiler from assuming that stop condition never changes, it will be read every time the condition gets evaluated. Neat, isn't it?
By looking at your code the problem isn't with usage of volatile keyword, the problem is that the expression i++ is not atomic. It actually is 3 step operation:
1) fetch value of i;
2) increment i;
3) save new value of i
When multi-threading comes into play, these might or might not be mixed with other thread's instructions.
So the execution might look like that as well:
1) T1: fetch i;
2) T2: fetch i;
3) T1: increment i;
4) T2: increment i;
5) T1: save i;
6) T2: save i;
If i was 0 you thought you will get 2 as the output, and here's 1 instead.
Go with synchronization, which is pretty simple when not overused and well thought.
Suggested read on synchronization
If two threads are both reading and writing to a shared variable, then using the volatile keyword for that is not enough. You need to use synchronization in that case to guarantee that the reading and writing of the variable is atomic.
Therefore you need to use synchronization when you modify the i value.
im trying to write a program in which two threads are created and the output should be like 1st thread prints 1 and the next thread prints 2 ,1st thread again prints 3 and so on. im a beginner so pls help me clearly. i thought thread share the same memory so they will share the i variable and print accordingly. but in output i get like thread1: 1, thread2 : 1, thread1: 2, thread2 : 2 nd so on. pls help. here is my code
class me extends Thread
{
public int name,i;
public void run()
{
for(i=1;i<=50;i++)
{
System.out.println("Thread" + name + " : " + i);
try
{
sleep(1000);
}
catch(Exception e)
{
System.out.println("some problem");
}
}
}
}
public class he
{
public static void main(String[] args)
{
me a=new me();
me b=new me();
a.name=1;
b.name=2;
a.start();
b.start();
}
}
First off you should read this http://www.oracle.com/technetwork/java/codeconventions-135099.html.
Secondly the class member variables are not shared memory. You need to explicitly pass an object (such as the counter) to both objects, such that it becomes shared. However, this will still not be enough. The shared memory can be cached by the threads so you will have race-conditions. To solve this you will need to use a Lock or use an AtomicInteger
It seems what you want to do is:
Write all numbers from 1 to 50 to System.out
without any number being printed multiple times
with the numbers being printed in order
Have this execution be done by two concurrent threads
First, let's look at what is happening in your code: Each number is printed twice. The reason for this is that i is an instance variable of me, your Thread. So each Thread has its own i, i.e., they do not share the value.
To make the two threads share the same value, we need to pass the same value when constructing me. Now, doing so with the primitive int won't help us much, because by passing an int we are not passing a reference, hence the two threads will still work on independent memory locations.
Let us define a new class, Value which holds the integer for us: (Edit: The same could also be achieved by passing an array int[], which also holds the reference to the memory location of its content)
class Value{
int i = 1;
}
Now, main can instantiate one object of type Value and pass the reference to it to both threads. This way, they can access the same memory location.
class Me extends Thread {
final Value v;
public Me(Value v){
this.v = v;
}
public void run(){
for(; v.i < 50; v.i++){
// ...
}
public static void main(){
Value valueInstance = new Value();
Me a = new Me(valueInstance);
Me b = new Me(valueInstance);
}
}
Now i isn't printed twice each time. However, you'll notice that the behavior is still not as desired. This is because the operations are interleaved: a may read i, let's say, the value is 5. Next, b increments the value of i, and stores the new value. i is now 6. However, a did still read the old value, 5, and will print 5 again, even though b just printed 5.
To solve this, we must lock the instance v, i.e., the object of type Value. Java provides the keyword synchronized, which will hold a lock during the execution of all code inside the synchronized block. However, if you simply put synchronize in your method, you still won't get what you desire. Assuming you write:
public void run(){ synchronized(v) {
for(; v.i < 50; v.i++) {
// ...
}}
Your first thread will acquire the lock, but never release it until the entire loop has been executed (which is when i has the value 50). Hence, you must release the lock somehow when it is safe to do so. Well... the only code in your run method that does not depend on i (and hence does not need to be locking) is sleep, which luckily also is where the thread spends the most time in.
Since everything is in the loop body, a simple synchronized block won't do. We can use Semaphore to acquire a lock. So, we create a Semaphore instance in the main method, and, similar to v, pass it to both threads. We can then acquire and release the lock on the Semaphore to let both threads have the chance to get the resource, while guaranteeing safety.
Here's the code that will do the trick:
public class Me extends Thread {
public int name;
final Value v;
final Semaphore lock;
public Me(Value v, Semaphore lock) {
this.v = v;
this.lock = lock;
}
public void run() {
try {
lock.acquire();
while (v.i <= 50) {
System.out.println("Thread" + name + " : " + v.i);
v.i++;
lock.release();
sleep(100);
lock.acquire();
}
lock.release();
} catch (Exception e) {
System.out.println("some problem");
}
}
public static void main(String[] args) {
Value v = new Value();
Semaphore lock = new Semaphore(1);
Me a = new Me(v, lock);
Me b = new Me(v, lock);
a.name = 1;
b.name = 2;
a.start();
b.start();
}
static class Value {
int i = 1;
}
}
Note: Since we are acquiring the lock at the end of the loop, we must also release it after the loop, or the resource will never be freed. Also, I changed the for-loop to a while loop, because we need to update i before releasing the lock for the first time, or the other thread can again read the same value.
Check the below link for the solution. Using multiple threads we can print the numbers in ascending order
http://cooltekhie.blogspot.in/2017/06/#987628206008590221