Java Volatile Variable - java

I am trying to understand volatile usage by the below example. I expect it to print 10 first and then 15 second. But most of the time i end getting 10 and 10.
Is some thing with the below code itself.
class T implements Runnable {
private volatile int x = 10;
#Override
public void run() {
if(x==10) {
System.out.println(x);
x = x+ 5;
} else if(x==15) {
System.out.println(x);
}
}
}
public class Prep {
public static void main(String [] args) {
T t1 = new T();
new Thread(t1).start();
new Thread(t1).start();
}
}

You just have a race condition: both threads run in parallel, and thus you have (for example)
thread 1 tests if x == 10 (true)
thread 2 tests if x == 10 (true)
thread 1 prints 10
thread 2 prints 10
...
The fact that x is volatile here is irrelevant. The only thing that volatile guarantees in this example is that if thread 1 has already incremented x when thread 2 reads its value, then thread 2 will see the incremented value. But it doesn't mean that the two threads can't run in parallel as shown above.

This will work :
public static void main(String[] args) {
T t1 = new T();
new Thread(t1).start();
try {
Thread.currentThread().sleep(1000); // sleeping for sometime .
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
new Thread(t1).start();
}
answer : 10 15
Reason : The operations
if(x==10) {
System.out.println(x);
might have executed first for the first thread, then context would have switched back to Thread2 (race condition as JB Nizet explains..) so when both threads print the value of x, it is still 10.

Related

I don't get how threads work in this case

The following code is shows how no race condition in thread works, but I don't get the difference between with the synchronized and without it. I thought the static variable counter will be added to 20000 anyway but it turned out that without synchronized counter would be less than 20000. Can you please explain how threads work in this case? Also, in Java, are threads are actually not running "concurrently", instead are they taking turns to run for a while?
public class NoRaceCondition implements Runnable {
private static int counter = 0;
private static Object gateKeeper = new Object();
public static void main(String[] args) {
Thread t1 = new Thread(new NoRaceCondition());
Thread t2 = new Thread(new NoRaceCondition());
t1.start();
t2.start();
try {
t1.join();
t2.join();
} catch (InterruptedException e) { e.printStackTrace(); }
System.out.printf("counter = %d\n", counter);
}
public void run() {
synchronized (gateKeeper) {
for (int i = 0; i < 10000; i++) {
{
counter++;
}
}
}
}
}
You can think of count++ as 3 separate steps.
read the value of count
increment the value
override count with the new incremented value
When multiple thread execute the above steps concurrently, race conditions may occur. 1 example of race condition is
Let count = 1
Let there be 2 threads named A and B
Thread A reads the value of count and get 1
Thread B reads the value of count and get 1
Thread A increments its value and get 2
Thread B increments its value and get 2
Thread A writes the value to count
count is now 2
Thread B writes the value to count
count is now 2 again when it's expected to be 3 after 2 increments

Multithreading - Why does the following program behave this weirdly?

The outline of the program:
We have two threads (t1 and t2) that write an integer value, then flush the written value to RAM.
Another thread (t3) checks whether the value coincidences with the one written by t1or t2, and if not, prints it.
public class Container
{
int a;
volatile boolean b;
public static void main(String[] args)
{
Container container = new Container();
Thread t1 = new Thread()
{
#Override
public void run()
{
for (;;)
{
container.a = 409;
container.b ^= container.b;
}
}
};
Thread t2 = new Thread()
{
#Override
public void run()
{
for (;;)
{
container.a = 102;
container.b ^= container.b;
}
}
};
Thread t3 = new Thread()
{
#Override
public void run()
{
try
{
Thread.sleep(100);
} catch (InterruptedException e)
{
e.printStackTrace();
}
for (;;)
{
if (container.a != 409 && container.a != 102 )
System.out.println(container.a);
}
}
};
t1.start();
t2.start();
t3.start();
}
}
What I thought would happen:
Since a isn't volatile, I thought t3 would cache a and just never print anything.
What actually happens:
For a second or so (no matter long you let t3sleep), it prints in rapid succession either 102 or 409. Then, printing stops (forever).
What exactly happens here?
container.a not being volatile doesn't mean it's mandatorily cached by t3. All it means is that there are no guarantees whether it will be or not.
The reason it is free to print any value is the time-of-check-to-time-of-use problem here:
if (container.a != 409 && container.a != 102 )
System.out.println(container.a);
As for why this exact behaviour on the exact environment you tested it in, we can only guess. But my money would be on the theory that while the code is run as interpreted, it will go and read container.a every time, but once it's compiled to native code by Hotspot, the value is only loaded into a register once, and that's the end of it. You can verify this hypothesis by using the -XX:+PrintCompilation command line flag.

Why can't the main thread compare two variables that are updated by other threads?

I want to write two Threads that increment a number and decrement a number, and a main Thread that determines when the two numbers are equal. For example, one number starts at 0 and the other number starts at 10... When they are both 5, the main Thread should recognize they are equal and print "They meet!".
In this code, the main Thread can't not compare numup and numdown successfully:
public class Number implements Runnable {
public static int numup = 0;
public static int numdown = 10;
public Number() {
}
public static void main(String args[]) {
Number number = new Number();
Thread T1 = new Thread(number, "up");
Thread T2 = new Thread(number, "down");
T1.start();
T2.start();
while (true) {
if (numup == 5 && numdown == 5) {
System.out.println("Meet!");
System.exit(0);
}
}
}
public void run() {
while (true) {
if (Thread.currentThread().getName().equals("up")) {
numup++;
System.out.println(numup);
} else if (Thread.currentThread().getName().equals("down")) {
numdown--;
System.out.println(numdown);
}
try {
Thread.sleep(1000);
} catch (Exception e) {
System.out.println("wake!");
}
}
}
}
The failed result:
1
9
8
2
7
3
6
4
5
5
6
4
7
3
8
2
1
9
However, when I make the main Thread sleep a few milliseconds, it works:
public class Number implements Runnable {
public static int numup = 0;
public static int numdown = 10;
public Number() {
}
public static void main(String args[]) {
Number number = new Number();
Thread T1 = new Thread(number, "up");
Thread T2 = new Thread(number, "down");
T1.start();
T2.start();
while (true) {
try {
Thread.sleep(10);
} catch (Exception e) {
System.out.println(Thread.currentThread().getName() + "was waked!");
}
if (numup == 5 && numdown == 5) {
System.out.println("They Meet!");
System.exit(0);
}
}
}
public void run() {
while (true) {
if (Thread.currentThread().getName().equals("up")) {
numup++;
System.out.println(numup);
} else if (Thread.currentThread().getName().equals("down")) {
numdown--;
System.out.println(numdown);
}
try {
Thread.sleep(1000);
} catch (Exception e) {
System.out.println("wake!");
}
}
}
}
The successful result:
1
9
2
8
3
7
4
6
5
5
They Meet!
Why does the added delay make it work?
This could be because of the CPU cache. When the number thread updates the value of the variable (this goes from its CPU cache to main memory) by then the CPU cache of the corresponding main thread might not have got updated.
So when main thread check's the value of the variable it was still the old value.
You can use Volatile. OR
Use AtomicInteger for these operations.
You can refer to this link.
In a multithreaded application where the threads operate on non-volatile variables, each thread may copy variables from main memory into a CPU cache while working on them, for performance reasons. If your computer contains more than one CPU, each thread may run on a different CPU. That means, that each thread may copy the variables into the CPU cache of different CPUs.
With non-volatile variables there are no guarantees about when the Java Virtual Machine (JVM) reads data from main memory into CPU caches, or writes data from CPU caches to main memory.
Volatile:
public static volatile int numup = 0;
public static volatile int numdown = 10;
Atomic Integer:
import java.util.concurrent.atomic.AtomicInteger;
public class Number implements Runnable {
public static AtomicInteger numup = new AtomicInteger(0);
public static AtomicInteger numdown = new AtomicInteger(10);
public Number() {
}
public static void main(String args[]) {
Number number = new Number();
Thread T1 = new Thread(number, "up");
Thread T2 = new Thread(number, "down");
T1.start();
T2.start();
while (true) {
if (numup.get() == 5 && numdown.get() == 5) {
System.out.println("Meet!");
System.exit(0);
}
}
}
public void run() {
while (true) {
if (Thread.currentThread().getName().equals("up")) {
numup.incrementAndGet();
System.out.println(numup);
} else if (Thread.currentThread().getName().equals("down")) {
numdown.decrementAndGet();
System.out.println(numdown);
}
try {
Thread.sleep(1000);
} catch (Exception e) {
System.out.println("wake!");
}
}
}
}
Quick answer - add volatile modifier to numdown and numup.
Long answer:
Your problem is that other thread can't see that numdown and numup has changed because of couple of reasons:
JVM may optimize and reorder the execution order of bytecode instructions.
Modern processors also do instruction reordering.
The value is cached in processor's cache line (L1, L2, L3 cache level).
So, when you introduce a volatile variable it is guaranteed by java that writes from one thread will have happen-before relationships with reads form another thus making changes visible to the another thread. On more low-level it could introduce a memory barrier
Anyway, it would not fit into the SO answer to explain properly how it's works, but there is a number of excellent resources you could read/watch if you're interested to dive deeper into the topic.
https://zeroturnaround.com/rebellabs/java-memory-model-pragmatics-by-aleksey-shipilev/
Do you ever use the volatile keyword in Java?
http://mechanical-sympathy.blogspot.com/2011/07/memory-barriersfences.html
Cheers!
Interesting one and a good answer given by Yegor. Just to add my observation that the program halts even if you write the if (numup == 5 && numdown == 5) check inside the while loop of the run() method.
In case you want to try out with the volatile keyword.
public static volatile int numup = 0;
public static volatile int numdown = 10;
volatile keyword will ensure that your threads won't cache the value of the variable and will always retrieve it from the main memory.

How to run two threads at the same time in java

I am new to java and I am trying to learn about threads.
I am expecting an output of alternate hello this is thread one and hello this is thread two. but the output I get is as follows:
hello this is thread one
hello this is thread one
hello this is thread one
hello this is thread one
hello this is thread one
hello this is thread two
hello this is thread two
hello this is thread two
hello this is thread two
hello this is thread two
Below is my code. Can anyone please help me out to why I am getting this output as opposed to expected. And what is it that I can do to run the two threads in parallel.
public class ThreadDemo {
public static void main(String args[]) {
// This is the first block of code
Thread thread = new Thread() {
public void run() {
for (int i = 0; i < 10; i += 2) {
System.out.println("hello this is thread one");
}
}
};
// This is the second block of code
Thread threadTwo = new Thread() {
public void run() {
for (int i = 0; i < 10; i += 2) {
System.out.println("hello this is thread two");
}
}
};
// These two statements are in the main method and begin the two
// threads.
// This is the third block of code
thread.start();
// This is the fourth block of code
threadTwo.start();
}
}
Just because threads may interlace does not mean that they will. Your threads simply run too fast. Try adding Thread.sleep() to make them run longer.
The problem here is that PrintStream is synchronized which is not fair.
final Lock lock = new ReentrantLock(true); //create fair lock
//after running this code change it to
//ReentrantLock(false); to see what happens
// This is the first block of code
Thread thread = new Thread() {
public void run() {
for (int i = 0; i < 10; i += 2) {
lock.lock();
System.out.println("hello this is thread one");
lock.unlock();
}
}
};
// This is the second block of code
Thread threadTwo = new Thread() {
public void run() {
for (int i = 0; i < 10; i += 2) {
lock.lock();
System.out.println("hello this is thread two");
lock.unlock();
}
}
};
// These two statements are in the main method and begin the two
// threads.
// This is the third block of code
thread.start();
// This is the fourth block of code
threadTwo.start();
when a lock is fair it will be alot slower, but when its not fair as in your first case it keeps grabbing the lock over and over before the other thread gets a chance to take it. A fair lock is like a queue. Whoever is queued to take it next gets it.
Depending on the number of CPUs and/or CPU cores, multi-threading may only be simulated by your CPU by giving each thread a certain number of time before another thread is scheduled. See also Wikipedia on "Preemptive Multitasking"
Also, given today's CPUs and many cores and their speed, it may also be that the execution of the first thread already finished before the second one is started.
Also, both threads are battling for the lock in System.out, so they will lock each other out.
Let the threads run for longer times (higher number of iterations), and you will see the interleaving you are expecting.
Your code would work too..add sleep in the first object.
// This is the first block of code
Thread thread = new Thread() {
public void run() {
for (int i = 0; i < 10; i += 2) {
System.out.println("hello this is thread one");
try {
sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
If you want to have the threads' bodies wait until both threads are running, you can use something like a CountDownLatch, which can block until its internal counter counts down to zero:
final CountDownLatch latch = new CountDownLatch(2);
Thread thread = new Thread() {
#Override public void run() {
latch.countDown();
latch.await(); // Execution waits here until latch reaches zero.
// Rest of the method.
}
}
Thread threadTwo = new Thread() {
#Override public void run() {
latch.countDown();
latch.await(); // Execution waits here until latch reaches zero.
// Rest of the method.
}
}
thread.start();
threadTwo.start();
(Exception handling omitted for clarity)
This will guarantee that the "interesting bit" of the two threads' run methods will be executing at the same time. However, because of the unfair synchronization on the println() method you are calling, there is no guarantee of how the messages printed by the two threads will be interleaved:
Sometimes they might "perfectly" interleave (1, 2, 1, 2, ...)
Sometimes a few of one might be printed without anything from the other (1, 1, 2, 1, 2, 2, 2, ...)
Sometimes one might print all of its messages before the other (1, 1, 1, 1, 2, 2, 2, 2).
Below code is working...
public class ThreadDemo {
public static void main(String args[]) throws InterruptedException {
// This is the first block of code
Thread thread = new Thread() {
public void run() {
for (int i = 0; i < 10; i += 2) {
System.out.println("hello this is thread one");
try {
Thread.sleep(100);
} catch (InterruptedException ex) {
Logger.getLogger(ThreadDemo.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
};
// This is the second block of code
Thread threadTwo = new Thread() {
public void run() {
for (int i = 0; i < 10; i += 2) {
System.out.println("hello this is thread two");
try {
Thread.sleep(100);
} catch (InterruptedException ex) {
Logger.getLogger(ThreadDemo.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
};
// These two statements are in the main method and begin the two
// threads.
// This is the third block of code
thread.start();
// This is the fourth block of code
threadTwo.start();
}
}
Your code is working as expected, there is absolutely no guarantee that your implementation will execute in the pre-defined manner you are expecting.
I would suggest that you look at other methods of implementing multithreaded code such as join(), sleep() and finding one that better suits your needs.

Want a code for the difference between synchronized and asynchronized method

I am trying to set the difference between synchronized and unsynchronized methods.. I have tried following code
class Counter {
private int counter = 10;
public int getCounter() {
return counter;
}
public synchronized void doIncrementAndDecrement() {
counter++;
keepBusy(500);
counter--;
}
public void keepBusy(int howLong) { // (D)
long curr = System.currentTimeMillis();
while (System.currentTimeMillis() < curr + howLong)
;
}
}
class MyCounterThread extends Thread {
Counter c;
public MyCounterThread(Counter c, String name) {
// TODO Auto-generated constructor stub
super(name);
this.c = c;
start();
}
#Override
public void run() {
for (;;) {
c.doIncrementAndDecrement();
sleepForSometime();
System.out.println(c.getCounter());
}
}
public void sleepForSometime() { // (D)
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class UnSynchronizedExapmle {
public static void main(String[] args) throws InterruptedException {
Counter c = new Counter();
MyCounterThread t1 = new MyCounterThread(c, "A");
MyCounterThread t2 = new MyCounterThread(c, "B");
MyCounterThread t3 = new MyCounterThread(c, "C");
}
}
So above i have doIncrementAndDecrement() synchronized method..
So i expected the value of counter should be 10 every time. But this wont happen i have the output is like
10
10
11
10
10
10
10
11
10
10
11
10
11
11
10
10
11
10
11
10
10
10
11
10
10
11
10
So please help me why this happens.. Or any blog/article for explaining difference between synchronized and asynchronized methods
Your getCounter() method is not synchronized. So even though one thread might be locking the method, another thread can still access and print your counter variable
You codes do not synchronized the getCounter method so that System.out.println may output the innerstate of counter. synchronized on method is as same as synchronized(this).
... what difference it make if i write Thread.sleep() in my keepBusy() method.. because the output is quite different in both case.
What it does is to make keepBusy() take a long time, and hence it makes getCounter() wait for a long time.
The difference in the output is due to the synchronization which prevents getCounter() from ever "seeing" the counter in the incremented state.
I mean what do the difference make Thread.sleep() and the above while loop in keepBusy() method make in terms of thread scheduling or locking..
It makes no difference.
For the record, it would bad idea for a real program to have a method like keepBusy() that sleeps in a synchronized method or block. The sleep causes any other thread that is trying to synchronize on the target object to be blocked ... and that's liable to reduce your application's actual parallelism.

Categories

Resources