Data Races on individual elements of an AtomicReference - java

I had a question related to accessing individual elements via an Atomic Reference.
If I have an IntegerArray and an atomic reference to it;will reading and writing to individual elements of the array via the AtomicReference variable cause data races?
In the code below: num is an Integer Array with aRnumbers being the atomic reference to the array.
In threads 1 and 2; I access aRnumbers.get()[1] and increment it by 1.
I am able to access individual elements via the atomic reference without data races to accurate results each time with 22 as the output of aRnumbers.get()[1] in the main thread after both threads complete.
But,since the atomic reference is defined on the array and not on the individual elements; shouldn't there be a data race in this case leading to 21/22 as the output?
Isn't having data races in this case the motivation for having a AtomicIntegerArray data structure which provides a separate AtomicReference to each element?
Please find below the java code that i am trying to run.Could anyone kindly let me know where I am going wrong.
import java.util.concurrent.atomic.AtomicReference;
public class AtomicReferenceExample {
private static int[] num= new int[2];
private static AtomicReference<int[]> aRnumbers;
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(new MyRun1());
Thread t2 = new Thread(new MyRun2());
num[0]=10;
num[1]=20;
aRnumbers = new AtomicReference<int[]>(num);
System.out.println("In Main before:"+aRnumbers.get()[0]+aRnumbers.get()[1]);
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println("In Main after:"+aRnumbers.get()[0]+aRnumbers.get()[1]);
}
static class MyRun1 implements Runnable {
public void run() {
System.out.println("In T1 before:"+aRnumbers.get()[1]);
aRnumbers.get()[1]=aRnumbers.get()[1]+1;
}
}
static class MyRun2 implements Runnable {
public void run() {
System.out.println("In T2 before:"+aRnumbers.get()[1]);
aRnumbers.get()[1]=aRnumbers.get()[1]+1;
}
}
}

shouldn't there be a data race in this case leading to 21/22 as the output?
Indeed there is. Your thread are so short lived that most likely they are not running at the same time.
Isn't having data races in this case the motivation for having a AtomicIntegerArray data structure which provides a separate AtomicReference to each element?
Yes, it is.
Could anyone kindly let me know where I am going wrong.
Starting a thread takes 1 - 10 milli-seconds.
Incrementing a value like this even without the code being JITed is likely to take << 50 microseconds. If it was optimised it would take about 50 - 200 nano-seconds per increment.
As starting athread takes about 20 - 200x longer than the operating they won't be running at the same time so there is no race condition.
Try incrementing the value a few million times, so you have a race condition because both threads are running at the same time.

Incrementing an element consists of three steps:
Reading the value.
Incrementing the value.
Writing the value back.
A race condition can occur. Take an example: Thread 1 reads the value (let's say 20). Task switch. Thread 2 reads the value (20 again), increments it and writes it back (21). Task switch. The first thread increments the value and writes it back (21). So while 2 incrementing operations took place, the final value is still incremented only by one.
The data structure does not help in this case. A thread safe collection helps keeping the structure consistent when concurrent threads are adding, accessing and removing elements. But here you need to lock access to an element during the three steps of the increment operation.

Related

Atomic Integers values are not getting updated in threads

I have defined an atomicinterger variable in class. The class also extends thread class .I have created two threads and incrementing the value of the atomic integer in run method .I was excepting the value of 2 after running two threads, But I am getting value as 1. Please let me know what went wrong in the below code.
public class AtomicIntergerTest extends Thread {
AtomicInteger i = new AtomicInteger();
int j = 0;
#Override
public void run() {
i.incrementAndGet();
}
public static void main(String[] args) throws InterruptedException {
// TODO Auto-generated method stub
AtomicIntergerTest th1 = new AtomicIntergerTest();
AtomicIntergerTest th2 = new AtomicIntergerTest();
th1.start();
th2.start();
th1.join();
th2.join();
System.out.println(th2.i.get());
}
}
Because AtomicInteger i = new AtomicInteger(); creates one AtomicInteger per instance. You wanted
static AtomicInteger i = new AtomicInteger();
You said:
I am still confused if have have a static integer i can get the same data visible across the all threads with that i can achieve my thread safety
You misunderstand. No you can't.
The VM basically works like this:
For any given field, all threads have a local copy of that field, and they all have an unfair coin. They flip it anytime they read or write to it. If the coin lands heads, they sync the field and read/write it. If the coin lands tails, they read/write the copy. The coin is unfair, in that it will mess with you: Always flip heads during tests and on your machine, flip tails a few times juuuuust when giving a demo to that important customer.
Thus, if we have this code running in one thread:
x = x + 1;
and the same code in another thread, x may only increment once, because the second thread read it's clone copy and thus the first thread's increment is missed. Or not. Maybe today you tried 100 times and the number ended up +2 every time. And then the next song on your winamp starts or the phase of the moon changes and now it seems to reliably add only 1. It can all happen, which is why such code is fundamentally broken. You should not interact with a field from multiple threads unless you've taken great care to streamline it.
You cannot force the coin, unless you establish so-called comes-before or comes-after relationships. You do this by using volatile or synchronized, or by calling code that does that. It gets complicated. Quickly.
AtomicInteger is a different solution. It is, well, atomic. If you have a thread with:
atomicInt.incrementAndGet();
and another one with the same thing, after they've both ran, that atomicInt has been incremented by 2, guaranteed.

confused about java while loop ,hope anyone can help me .? [duplicate]

At work today, I came across the volatile keyword in Java. Not being very familiar with it, I found this explanation.
Given the detail in which that article explains the keyword in question, do you ever use it or could you ever see a case in which you could use this keyword in the correct manner?
volatile has semantics for memory visibility. Basically, the value of a volatile field becomes visible to all readers (other threads in particular) after a write operation completes on it. Without volatile, readers could see some non-updated value.
To answer your question: Yes, I use a volatile variable to control whether some code continues a loop. The loop tests the volatile value and continues if it is true. The condition can be set to false by calling a "stop" method. The loop sees false and terminates when it tests the value after the stop method completes execution.
The book "Java Concurrency in Practice," which I highly recommend, gives a good explanation of volatile. This book is written by the same person who wrote the IBM article that is referenced in the question (in fact, he cites his book at the bottom of that article). My use of volatile is what his article calls the "pattern 1 status flag."
If you want to learn more about how volatile works under the hood, read up on the Java memory model. If you want to go beyond that level, check out a good computer architecture book like Hennessy & Patterson and read about cache coherence and cache consistency.
“… the volatile modifier guarantees that any thread that reads a field will see the most recently written value.” - Josh Bloch
If you are thinking about using volatile, read up on the package java.util.concurrent which deals with atomic behaviour.
The Wikipedia post on a Singleton Pattern shows volatile in use.
Volatile(vɒlətʌɪl): Easily evaporated at normal temperatures
Important point about volatile:
Synchronization in Java is possible by using Java keywords synchronized and volatile and locks.
In Java, we can not have synchronized variable. Using synchronized keyword with a variable is illegal and will result in compilation error. Instead of using the synchronized variable in Java, you can use the java volatile variable, which will instruct JVM threads to read the value of volatile variable from main memory and don’t cache it locally.
If a variable is not shared between multiple threads then there is no need to use the volatile keyword.
source
Example usage of volatile:
public class Singleton {
private static volatile Singleton _instance; // volatile variable
public static Singleton getInstance() {
if (_instance == null) {
synchronized (Singleton.class) {
if (_instance == null)
_instance = new Singleton();
}
}
return _instance;
}
}
We are creating instance lazily at the time the first request comes.
If we do not make the _instance variable volatile then the Thread which is creating the instance of Singleton is not able to communicate to the other thread. So if Thread A is creating Singleton instance and just after creation, the CPU corrupts etc, all other threads will not be able to see the value of _instance as not null and they will believe it is still assigned null.
Why does this happen? Because reader threads are not doing any locking and until the writer thread comes out of a synchronized block, the memory will not be synchronized and value of _instance will not be updated in main memory. With the Volatile keyword in Java, this is handled by Java itself and such updates will be visible by all reader threads.
Conclusion: volatile keyword is also used to communicate the content of memory between threads.
Example usage of without volatile:
public class Singleton {
private static Singleton _instance; //without volatile variable
public static Singleton getInstance() {
if (_instance == null) {
synchronized(Singleton.class) {
if (_instance == null)
_instance = new Singleton();
}
}
return _instance;
}
}
The code above is not thread-safe. Although it checks the value of instance once again within the synchronized block (for performance reasons), the JIT compiler can rearrange the bytecode in a way that the reference to the instance is set before the constructor has finished its execution. This means the method getInstance() returns an object that may not have been initialized completely. To make the code thread-safe, the keyword volatile can be used since Java 5 for the instance variable. Variables that are marked as volatile get only visible to other threads once the constructor of the object has finished its execution completely.
Source
volatile usage in Java:
The fail-fast iterators are typically implemented using a volatile counter on the list object.
When the list is updated, the counter is incremented.
When an Iterator is created, the current value of the counter is embedded in the Iterator object.
When an Iterator operation is performed, the method compares the two counter values and throws a ConcurrentModificationException if they are different.
The implementation of fail-safe iterators is typically light-weight. They typically rely on properties of the specific list implementation's data structures. There is no general pattern.
volatile is very useful to stop threads.
Not that you should be writing your own threads, Java 1.6 has a lot of nice thread pools. But if you are sure you need a thread, you'll need to know how to stop it.
The pattern I use for threads is:
public class Foo extends Thread {
private volatile boolean close = false;
public void run() {
while(!close) {
// do work
}
}
public void close() {
close = true;
// interrupt here if needed
}
}
In the above code segment, the thread reading close in the while loop is different from the one that calls close(). Without volatile, the thread running the loop may never see the change to close.
Notice how there's no need for synchronization
A variable declared with volatile keyword, has two main qualities which make it special.
If we have a volatile variable, it cannot be cached into the computer's(microprocessor) cache memory by any thread. Access always happened from main memory.
If there is a write operation going on a volatile variable, and suddenly a read operation is requested, it is guaranteed that the write operation will be finished prior to the read operation.
Two above qualities deduce that
All the threads reading a volatile variable will definitely read the latest value. Because no cached value can pollute it. And also the read request will be granted only after the completion of the current write operation.
And on the other hand,
If we further investigate the #2 that I have mentioned, we can see that volatile keyword is an ideal way to maintain a shared variable which has 'n' number of reader threads and only one writer thread to access it. Once we add the volatile keyword, it is done. No any other overhead about thread safety.
Conversly,
We can't make use of volatile keyword solely, to satisfy a shared variable which has more than one writer thread accessing it.
One common example for using volatile is to use a volatile boolean variable as a flag to terminate a thread. If you've started a thread, and you want to be able to safely interrupt it from a different thread, you can have the thread periodically check a flag. To stop it, set the flag to true. By making the flag volatile, you can ensure that the thread that is checking it will see it has been set the next time it checks it without having to even use a synchronized block.
No one has mentioned the treatment of read and write operation for long and double variable type. Reads and writes are atomic operations for reference variables and for most primitive variables, except for long and double variable types, which must use the volatile keyword to be atomic operations. #link
Yes, volatile must be used whenever you want a mutable variable to be accessed by multiple threads. It is not very common usecase because typically you need to perform more than a single atomic operation (e.g. check the variable state before modifying it), in which case you would use a synchronized block instead.
Volatile
volatile -> synchronized[About]
volatile says for a programmer that the value always will be up to date. The problem is that the value can be saved on different types of hardware memory. For example it can be CPU registers, CPU cache, RAM... СPU registers and CPU cache belong to CPU and can not share a data unlike of RAM which is on the rescue in multithreading envirompment
volatile keyword says that a variable will be read and written from/to RAM memory directly. It has some computation footprint
Java 5 extended volatile by supporting happens-before[About]
A write to a volatile field happens-before every subsequent read of that field.
Read is after write
volatile keyword does not cure a race condition[About] situation to sove it use synchronized keyword[About]
As a result it safety only when one thread writes and others just read the volatile value
In my opinion, two important scenarios other than stopping thread in which volatile keyword is used are:
Double-checked locking mechanism. Used often in Singleton design
pattern. In this the singleton object needs to be declared volatile.
Spurious Wakeups. Thread may sometimes wake up from wait call even if no notify call has been issued. This behavior is called spurious wakeup. This can be countered by using a conditional variable (boolean flag). Put the wait() call in a while loop as long as the flag is true. So if thread wakes up from wait call due to any reasons other than Notify/NotifyAll then it encounters flag is still true and hence calls wait again. Prior to calling notify set this flag to true. In this case the boolean flag is declared as volatile.
Assume that a thread modifies the value of a shared variable, if you didn't use volatile modifier for that variable. When other threads want to read this variable's value, they don't see the updated value because they read the variable's value from the CPU's cache instead of RAM memory. This problem also known as Visibility Problem.
By declaring the shared variable volatile, all writes to the counter variable will be written back to main memory immediately. Also, all reads of the counter variable will be read directly from main memory.
public class SharedObject {
public volatile int sharedVariable = 0;
}
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. This can cause several problems which I will explain in the following sections.
Example:
Imagine a situation in which two or more threads have access to a shared object which contains a counter variable declared like this:
public class SharedObject {
public int counter = 0;
}
Imagine too, that only Thread 1 increments the counter variable, but both Thread 1 and Thread 2 may read the counter variable from time to time.
If the counter variable is not declared volatile there is no guarantee about when the value of the counter variable is written from the CPU cache back to main memory. This means, that the counter variable value in the CPU cache may not be the same as in main memory. This situation is illustrated here:
The problem with threads not seeing the latest value of a variable because it has not yet been written back to main memory by another thread, is called a "visibility" problem. The updates of one thread are not visible to other threads.
You'll need to use 'volatile' keyword, or 'synchronized' and any other concurrency control tools and techniques you might have at your disposal if you are developing a multithreaded application. Example of such application is desktop apps.
If you are developing an application that would be deployed to application server (Tomcat, JBoss AS, Glassfish, etc) you don't have to handle concurrency control yourself as it already addressed by the application server. In fact, if I remembered correctly the Java EE standard prohibit any concurrency control in servlets and EJBs, since it is part of the 'infrastructure' layer which you supposed to be freed from handling it. You only do concurrency control in such app if you're implementing singleton objects. This even already addressed if you knit your components using frameworkd like Spring.
So, in most cases of Java development where the application is a web application and using IoC framework like Spring or EJB, you wouldn't need to use 'volatile'.
volatile only guarantees that all threads, even themselves, are incrementing. For example: a counter sees the same face of the variable at the same time. It is not used instead of synchronized or atomic or other stuff, it completely makes the reads synchronized. Please do not compare it with other java keywords. As the example shows below volatile variable operations are also atomic they fail or succeed at once.
package io.netty.example.telnet;
import java.util.ArrayList;
import java.util.List;
public class Main {
public static volatile int a = 0;
public static void main(String args[]) throws InterruptedException{
List<Thread> list = new ArrayList<Thread>();
for(int i = 0 ; i<11 ;i++){
list.add(new Pojo());
}
for (Thread thread : list) {
thread.start();
}
Thread.sleep(20000);
System.out.println(a);
}
}
class Pojo extends Thread{
int a = 10001;
public void run() {
while(a-->0){
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
Main.a++;
System.out.println("a = "+Main.a);
}
}
}
Even you put volatile or not results will always differ. But if you use AtomicInteger as below results will be always same. This is same with synchronized also.
package io.netty.example.telnet;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
public class Main {
public static volatile AtomicInteger a = new AtomicInteger(0);
public static void main(String args[]) throws InterruptedException{
List<Thread> list = new ArrayList<Thread>();
for(int i = 0 ; i<11 ;i++){
list.add(new Pojo());
}
for (Thread thread : list) {
thread.start();
}
Thread.sleep(20000);
System.out.println(a.get());
}
}
class Pojo extends Thread{
int a = 10001;
public void run() {
while(a-->0){
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
Main.a.incrementAndGet();
System.out.println("a = "+Main.a);
}
}
}
While I see many good Theoretical explanations in the answers mentioned here, I am adding a practical example with an explanation here:
1.
CODE RUN WITHOUT VOLATILE USE
public class VisibilityDemonstration {
private static int sCount = 0;
public static void main(String[] args) {
new Consumer().start();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
return;
}
new Producer().start();
}
static class Consumer extends Thread {
#Override
public void run() {
int localValue = -1;
while (true) {
if (localValue != sCount) {
System.out.println("Consumer: detected count change " + sCount);
localValue = sCount;
}
if (sCount >= 5) {
break;
}
}
System.out.println("Consumer: terminating");
}
}
static class Producer extends Thread {
#Override
public void run() {
while (sCount < 5) {
int localValue = sCount;
localValue++;
System.out.println("Producer: incrementing count to " + localValue);
sCount = localValue;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
return;
}
}
System.out.println("Producer: terminating");
}
}
}
In the above code, there are two threads - Producer and Consumer.
The producer thread iterates over the loop 5 times (with a sleep of 1000 milliSecond or 1 Sec) in between. In every iteration, the producer thread increases the value of sCount variable by 1. So, the producer changes the value of sCount from 0 to 5 in all iterations
The consumer thread is in a constant loop and print whenever the value of sCount changes until the value reaches 5 where it ends.
Both the loops are started at the same time. So both the producer and consumer should print the value of sCount 5 times.
OUTPUT
Consumer: detected count change 0
Producer: incrementing count to 1
Producer: incrementing count to 2
Producer: incrementing count to 3
Producer: incrementing count to 4
Producer: incrementing count to 5
Producer: terminating
ANALYSIS
In the above program, when the producer thread updates the value of sCount, it does update the value of the variable in the main memory(memory from where every thread is going to initially read the value of variable). But the consumer thread reads the value of sCount only the first time from this main memory and then caches the value of that variable inside its own memory. So, even if the value of original sCount in main memory has been updated by the producer thread, the consumer thread is reading from its cached value which is not updated. This is called VISIBILITY PROBLEM .
2.
CODE RUN WITH VOLATILE USE
In the above code, replace the line of code where sCount is declared by the following :
private volatile static int sCount = 0;
OUTPUT
Consumer: detected count change 0
Producer: incrementing count to 1
Consumer: detected count change 1
Producer: incrementing count to 2
Consumer: detected count change 2
Producer: incrementing count to 3
Consumer: detected count change 3
Producer: incrementing count to 4
Consumer: detected count change 4
Producer: incrementing count to 5
Consumer: detected count change 5
Consumer: terminating
Producer: terminating
ANALYSIS
When we declare a variable volatile, it means that all reads and all writes to this variable or from this variable will go directly into the main memory. The values of these variables will never be cached.
As the value of the sCount variable is never cached by any thread, the consumer always reads the original value of sCount from the main memory(where it is being updated by producer thread). So, In this case the output is correct where both the threads prints the different values of sCount 5 times.
In this way, the volatile keyword solves the VISIBILITY PROBLEM .
Yes, I use it quite a lot - it can be very useful for multi-threaded code. The article you pointed to is a good one. Though there are two important things to bear in mind:
You should only use volatile if you
completely understand what it does
and how it differs to synchronized.
In many situations volatile appears,
on the surface, to be a simpler more
performant alternative to
synchronized, when often a better
understanding of volatile would make
clear that synchronized is the only
option that would work.
volatile doesn't actually work in a
lot of older JVMs, although
synchronized does. I remember seeing a document that referenced the various levels of support in different JVMs but unfortunately I can't find it now. Definitely look into it if you're using Java pre 1.5 or if you don't have control over the JVMs that your program will be running on.
Absolutely, yes. (And not just in Java, but also in C#.) There are times when you need to get or set a value that is guaranteed to be an atomic operation on your given platform, an int or boolean, for example, but do not require the overhead of thread locking. The volatile keyword allows you to ensure that when you read the value that you get the current value and not a cached value that was just made obsolete by a write on another thread.
Every thread accessing a volatile field will read its current value before continuing, instead of (potentially) using a cached value.
Only member variable can be volatile or transient.
There are two different uses of volatile keyword.
Prevents JVM from reading values from register (assume as cache), and forces its value to be read from memory.
Reduces the risk of memory in-consistency errors.
Prevents JVM from reading values in register, and forces its
value to be read from memory.
A busy flag is used to prevent a thread from continuing while the device is busy and the flag is not protected by a lock:
while (busy) {
/* do something else */
}
The testing thread will continue when another thread turns off the busy flag:
busy = 0;
However, since busy is accessed frequently in the testing thread, the JVM may optimize the test by placing the value of busy in a register, then test the contents of the register without reading the value of busy in memory before every test. The testing thread would never see busy change and the other thread would only change the value of busy in memory, resulting in deadlock. Declaring the busy flag as volatile forces its value to be read before each test.
Reduces the risk of memory consistency errors.
Using volatile variables reduces the risk of memory consistency errors, because any write to a volatile variable establishes a
"happens-before" relationship with subsequent reads of that same variable. This means that changes to a volatile variable are always visible to other threads.
The technique of reading, writing without memory consistency errors is called atomic action.
An atomic action is one that effectively happens all at once. An atomic action cannot stop in the middle: it either happens completely, or it doesn't happen at all. No side effects of an atomic action are visible until the action is complete.
Below are actions you can specify that are atomic:
Reads and writes are atomic for reference variables and for most
primitive variables (all types except long and double).
Reads and writes are atomic for all variables declared volatile
(including long and double variables).
Cheers!
Volatile does following.
1> Read and write of volatile variables by different threads are always from memory, not from thread's own cache or cpu register. So each thread always deals with the latest value.
2> When 2 different threads work with same instance or static variables in heap, one may see other's actions as out of order. See jeremy manson's blog on this. But volatile helps here.
Following fully running code shows how a number of threads can execute in predefined order and print outputs without using synchronized keyword.
thread 0 prints 0
thread 1 prints 1
thread 2 prints 2
thread 3 prints 3
thread 0 prints 0
thread 1 prints 1
thread 2 prints 2
thread 3 prints 3
thread 0 prints 0
thread 1 prints 1
thread 2 prints 2
thread 3 prints 3
To achieve this we may use the following full fledged running code.
public class Solution {
static volatile int counter = 0;
static int print = 0;
public static void main(String[] args) {
// TODO Auto-generated method stub
Thread[] ths = new Thread[4];
for (int i = 0; i < ths.length; i++) {
ths[i] = new Thread(new MyRunnable(i, ths.length));
ths[i].start();
}
}
static class MyRunnable implements Runnable {
final int thID;
final int total;
public MyRunnable(int id, int total) {
thID = id;
this.total = total;
}
#Override
public void run() {
// TODO Auto-generated method stub
while (true) {
if (thID == counter) {
System.out.println("thread " + thID + " prints " + print);
print++;
if (print == total)
print = 0;
counter++;
if (counter == total)
counter = 0;
} else {
try {
Thread.sleep(30);
} catch (InterruptedException e) {
// log it
}
}
}
}
}
}
The following github link has a readme, which gives proper explanation.
https://github.com/sankar4git/volatile_thread_ordering
From oracle documentation page, the need for volatile variable arises to fix memory consistency issues:
Using volatile variables reduces the risk of memory consistency errors, because any write to a volatile variable establishes a happens-before relationship with subsequent reads of that same variable.
This means that changes to a volatile variable are always visible to other threads. It also means that when a thread reads a volatile variable, it sees not just the latest change to the volatile, but also the side effects of the code that led up the change.
As explained in Peter Parker answer, in absence of volatile modifier, each thread's stack may have their own copy of variable. By making the variable as volatile, memory consistency issues have been fixed.
Have a look at jenkov tutorial page for better understanding.
Have a look at related SE question for some more details on volatile & use cases to use volatile:
Difference between volatile and synchronized in Java
One practical use case:
You have many threads, which need to print current time in a particular format for example : java.text.SimpleDateFormat("HH-mm-ss"). Yon can have one class, which converts current time into SimpleDateFormat and updated the variable for every one second. All other threads can simply use this volatile variable to print current time in log files.
Volatile Variables are light-weight synchronization. When visibility of latest data among all threads is requirement and atomicity can be compromised , in such situations Volatile Variables must be preferred. Read on volatile variables always return most recent write done by any thread since they are neither cached in registers nor in caches where other processors can not see. Volatile is Lock-Free. I use volatile, when scenario meets criteria as mentioned above.
volatile variable is basically used for instant update (flush) in main shared cache line once it updated, so that changes reflected to all worker threads immediately.
If you have a multithread system and these multiple threads work on some shared data, those threads will load data in their own cache. If we do not lock the resource, any change made in one thread is NOT gonna be available in another thread.
With a locking mechanism, we add read/write access to the data source. If one thread modifies the data source, that data will be stored in the main memory instead of in its cache. When others threads need this data, they will read it from the main memory. This will increase the latency dramatically.
To reduce the latency, we declare variables as volatile. It means that whenever the value of the variable is modified in any of the processors, the other threads will be forced to read it. It still has some delays but better than reading from the main memory.
Below is a very simple code to demonstrate the requirement of volatile for variable which is used to control the Thread execution from other thread (this is one scenario where volatile is required).
// Code to prove importance of 'volatile' when state of one thread is being mutated from another thread.
// Try running this class with and without 'volatile' for 'state' property of Task class.
public class VolatileTest {
public static void main(String[] a) throws Exception {
Task task = new Task();
new Thread(task).start();
Thread.sleep(500);
long stoppedOn = System.nanoTime();
task.stop(); // -----> do this to stop the thread
System.out.println("Stopping on: " + stoppedOn);
}
}
class Task implements Runnable {
// Try running with and without 'volatile' here
private volatile boolean state = true;
private int i = 0;
public void stop() {
state = false;
}
#Override
public void run() {
while(state) {
i++;
}
System.out.println(i + "> Stopped on: " + System.nanoTime());
}
}
When volatile is not used: you'll never see 'Stopped on: xxx' message even after 'Stopping on: xxx', and the program continues to run.
Stopping on: 1895303906650500
When volatile used: you'll see the 'Stopped on: xxx' immediately.
Stopping on: 1895285647980000
324565439> Stopped on: 1895285648087300
Demo: https://repl.it/repls/SilverAgonizingObjectcode
The volatile key when used with a variable, will make sure that threads reading this variable will see the same value . Now if you have multiple threads reading and writing to a variable, making the variable volatile will not be enough and data will be corrupted . Image threads have read the same value but each one has done some chages (say incremented a counter) , when writing back to the memory, data integrity is violated . That is why it is necessary to make the varible synchronized (diffrent ways are possible)
If the changes are done by 1 thread and the others need just to read this value, the volatile will be suitable.

Try to solving race condition without using any library in Java

I searched "java race condition" and saw a lot of articles, but none of them is what I am looking for.
I am trying to solve the race condition without using lock, synchronization, Thread.sleep something else. My code is here:
public class Test {
static public int amount = 0;
static public boolean x = false;
public static void main(String[] args) {
Thread a = new myThread1();
Thread b = new myThread2();
b.start();
a.start();
}
}
class myThread1 extends Thread {
public void run() {
for (int i = 0; i < 1000000; i++) {
if (i % 100000 == 0) {
System.out.println(i);
}
}
while(true){
Test.x = true;
}
}
}
class myThread2 extends Thread {
public void run() {
System.out.println("Thread 2: waiting...");
while (!Test.x) {
}
System.out.println("Thread 2: finish waiting!");
}
}
I expect the output should be:
Thread 2: waiting...
0
100000
200000
300000
400000
500000
600000
700000
800000
900000
Thread 2: finish waiting!
(Terminated normally)
But it actually is:
Thread 2: waiting...
0
100000
200000
300000
400000
500000
600000
700000
800000
900000
(And the program won't terminate)
After I added a statement to myThread2, changed
while (!Test.x) {
}
to
while (!Test.x) {
System.out.println(".");
}
The program terminate normally and the output is what I expected (except those ".')
I know when 2 threads execute concurrently, the CPU may arbitrarily switch to another before fetch the next instruction of machine code.
I thought it will be fine if one thread read a variable while another thread write to the variable. And I really don't get it why the program will not terminate normally. I also tried to add a Thread sleep statement inside the while loop of myThread1, but the program still will not terminate.
This question puzzled me few weeks, hope any one can help me please.
Try to declare x as volatile :
static public volatile boolean x = false;
Test.x isn't volatile and thus might not be synchronized between threads.
How the print-command in the second loop affects the overall behavior can't be predicted, but apparently in this case it causes x to be synchronized.
In general: if you omit all thread-related features of java, you can't produce any code, that has a well defined behavior. The minimum would be mark variables that are used by different threads as volatile and synchronize pieces of code, that my not run concurrently.
The shared variable x is being read and written from multiple threads without any synchronisation and hence only bad things can happen.
When you have the following,
while (!Test.x) {
}
The compiler might optimise this into an infinite loop since x (the non volatile variable) is not being changed inside the while loop, and this would prevent the program from terminating.
Adding a print statement will add more visibility since it has a synchronised block protecting System.out, this will lead into crossing the memory barrier and getting a fresh copy of Test.x.
You CAN NOT synchronise shared mutable state without using synchronisation constructs.
Much more better would be a LOCK object you may wait in Thread2 and send a notificytion in thread 1. You are currently active waiting in Thread2 and consume a lot of CPU resources.
Dummy code example:
main() {
Object lock = new Object();
Thread2 t2 = new Thread2(lock);
t2.start();
Thread1 t1 = new Thread1(lock);
t1.start();
...
}
class Thread1 {
Object lock = null;
public Thread1(Object lock) {
this.lock = lock;
...
}
public void run() {
...
synchronized (lock) {
lock.notifyAll();
}
}
} // end class Thread1
// similar Thread2
class Thread2 {
... constructor
public void run()
{
System.out.println("Thread 2: waiting...");
synchronized(lock) {
lock.wait();
}
System.out.println("Thread 2: finish waiting!");
}
....
This construct does not consume any CPU cycles without doing anything in "Thread2". You can create a custom number of "Thread2" instances and wait till "Thread1" is finished. You should "only" start all "Thread2" instances before "Thread1". Otherwise "Thread1" may finish before "Thread2" instances are started.
What you are really asking is, "Why does my program work as expected when I add a call to println()?"
Actions performed by one thread aren't generally required to be visible to other threads. The JVM is free to treat each thread as if it's operating in its own, private universe, which is often faster than trying to keep all other threads updated with events in that private universe.
If you have a need for some threads to stay up-to-date with some actions of another thread, you must "synchronize-with" those threads. If you don't, there's no guarantee threads will ever observe the actions of another.
Solving a race condition without a memory barrier is a nonsensical question. There's no answer, and no reason to look for one. Declare x to be a volatile field!
When you call System.out.println(), you are invoking a synchronized method, which, like volatile, acts as a memory barrier to synchronize with other threads. It appears to be sufficient in this case, but in general, even this is not enough to guarantee your program will work as expected. To guarantee the desired behavior, the first thread should acquire and release the same lock, System.out, after setting x to true.
Update:
Eric asks, "I am curious how volatile work, what has it done behind. I thought that everything can be created by addition, subtraction, compare, jumping, and assignment."
Volatile writes work by ensuring that values are written to a location that is accessible to all reading threads, like main memory, instead of something like a processor register or a data cache line.
Volatile reads work by ensuring that values are read from that shared location, instead of, for example, using a value cached in a register.
When Java byte codes are executed, they are translated to native instructions specific to the executing processor. The instructions necessary to make volatile work will vary, but the specification of the Java platform require that whatever the implementation, certain guarantees about visibility are met.

Java volatile key word senseless for some types? [duplicate]

At work today, I came across the volatile keyword in Java. Not being very familiar with it, I found this explanation.
Given the detail in which that article explains the keyword in question, do you ever use it or could you ever see a case in which you could use this keyword in the correct manner?
volatile has semantics for memory visibility. Basically, the value of a volatile field becomes visible to all readers (other threads in particular) after a write operation completes on it. Without volatile, readers could see some non-updated value.
To answer your question: Yes, I use a volatile variable to control whether some code continues a loop. The loop tests the volatile value and continues if it is true. The condition can be set to false by calling a "stop" method. The loop sees false and terminates when it tests the value after the stop method completes execution.
The book "Java Concurrency in Practice," which I highly recommend, gives a good explanation of volatile. This book is written by the same person who wrote the IBM article that is referenced in the question (in fact, he cites his book at the bottom of that article). My use of volatile is what his article calls the "pattern 1 status flag."
If you want to learn more about how volatile works under the hood, read up on the Java memory model. If you want to go beyond that level, check out a good computer architecture book like Hennessy & Patterson and read about cache coherence and cache consistency.
“… the volatile modifier guarantees that any thread that reads a field will see the most recently written value.” - Josh Bloch
If you are thinking about using volatile, read up on the package java.util.concurrent which deals with atomic behaviour.
The Wikipedia post on a Singleton Pattern shows volatile in use.
Volatile(vɒlətʌɪl): Easily evaporated at normal temperatures
Important point about volatile:
Synchronization in Java is possible by using Java keywords synchronized and volatile and locks.
In Java, we can not have synchronized variable. Using synchronized keyword with a variable is illegal and will result in compilation error. Instead of using the synchronized variable in Java, you can use the java volatile variable, which will instruct JVM threads to read the value of volatile variable from main memory and don’t cache it locally.
If a variable is not shared between multiple threads then there is no need to use the volatile keyword.
source
Example usage of volatile:
public class Singleton {
private static volatile Singleton _instance; // volatile variable
public static Singleton getInstance() {
if (_instance == null) {
synchronized (Singleton.class) {
if (_instance == null)
_instance = new Singleton();
}
}
return _instance;
}
}
We are creating instance lazily at the time the first request comes.
If we do not make the _instance variable volatile then the Thread which is creating the instance of Singleton is not able to communicate to the other thread. So if Thread A is creating Singleton instance and just after creation, the CPU corrupts etc, all other threads will not be able to see the value of _instance as not null and they will believe it is still assigned null.
Why does this happen? Because reader threads are not doing any locking and until the writer thread comes out of a synchronized block, the memory will not be synchronized and value of _instance will not be updated in main memory. With the Volatile keyword in Java, this is handled by Java itself and such updates will be visible by all reader threads.
Conclusion: volatile keyword is also used to communicate the content of memory between threads.
Example usage of without volatile:
public class Singleton {
private static Singleton _instance; //without volatile variable
public static Singleton getInstance() {
if (_instance == null) {
synchronized(Singleton.class) {
if (_instance == null)
_instance = new Singleton();
}
}
return _instance;
}
}
The code above is not thread-safe. Although it checks the value of instance once again within the synchronized block (for performance reasons), the JIT compiler can rearrange the bytecode in a way that the reference to the instance is set before the constructor has finished its execution. This means the method getInstance() returns an object that may not have been initialized completely. To make the code thread-safe, the keyword volatile can be used since Java 5 for the instance variable. Variables that are marked as volatile get only visible to other threads once the constructor of the object has finished its execution completely.
Source
volatile usage in Java:
The fail-fast iterators are typically implemented using a volatile counter on the list object.
When the list is updated, the counter is incremented.
When an Iterator is created, the current value of the counter is embedded in the Iterator object.
When an Iterator operation is performed, the method compares the two counter values and throws a ConcurrentModificationException if they are different.
The implementation of fail-safe iterators is typically light-weight. They typically rely on properties of the specific list implementation's data structures. There is no general pattern.
volatile is very useful to stop threads.
Not that you should be writing your own threads, Java 1.6 has a lot of nice thread pools. But if you are sure you need a thread, you'll need to know how to stop it.
The pattern I use for threads is:
public class Foo extends Thread {
private volatile boolean close = false;
public void run() {
while(!close) {
// do work
}
}
public void close() {
close = true;
// interrupt here if needed
}
}
In the above code segment, the thread reading close in the while loop is different from the one that calls close(). Without volatile, the thread running the loop may never see the change to close.
Notice how there's no need for synchronization
A variable declared with volatile keyword, has two main qualities which make it special.
If we have a volatile variable, it cannot be cached into the computer's(microprocessor) cache memory by any thread. Access always happened from main memory.
If there is a write operation going on a volatile variable, and suddenly a read operation is requested, it is guaranteed that the write operation will be finished prior to the read operation.
Two above qualities deduce that
All the threads reading a volatile variable will definitely read the latest value. Because no cached value can pollute it. And also the read request will be granted only after the completion of the current write operation.
And on the other hand,
If we further investigate the #2 that I have mentioned, we can see that volatile keyword is an ideal way to maintain a shared variable which has 'n' number of reader threads and only one writer thread to access it. Once we add the volatile keyword, it is done. No any other overhead about thread safety.
Conversly,
We can't make use of volatile keyword solely, to satisfy a shared variable which has more than one writer thread accessing it.
One common example for using volatile is to use a volatile boolean variable as a flag to terminate a thread. If you've started a thread, and you want to be able to safely interrupt it from a different thread, you can have the thread periodically check a flag. To stop it, set the flag to true. By making the flag volatile, you can ensure that the thread that is checking it will see it has been set the next time it checks it without having to even use a synchronized block.
No one has mentioned the treatment of read and write operation for long and double variable type. Reads and writes are atomic operations for reference variables and for most primitive variables, except for long and double variable types, which must use the volatile keyword to be atomic operations. #link
Yes, volatile must be used whenever you want a mutable variable to be accessed by multiple threads. It is not very common usecase because typically you need to perform more than a single atomic operation (e.g. check the variable state before modifying it), in which case you would use a synchronized block instead.
Volatile
volatile -> synchronized[About]
volatile says for a programmer that the value always will be up to date. The problem is that the value can be saved on different types of hardware memory. For example it can be CPU registers, CPU cache, RAM... СPU registers and CPU cache belong to CPU and can not share a data unlike of RAM which is on the rescue in multithreading envirompment
volatile keyword says that a variable will be read and written from/to RAM memory directly. It has some computation footprint
Java 5 extended volatile by supporting happens-before[About]
A write to a volatile field happens-before every subsequent read of that field.
Read is after write
volatile keyword does not cure a race condition[About] situation to sove it use synchronized keyword[About]
As a result it safety only when one thread writes and others just read the volatile value
In my opinion, two important scenarios other than stopping thread in which volatile keyword is used are:
Double-checked locking mechanism. Used often in Singleton design
pattern. In this the singleton object needs to be declared volatile.
Spurious Wakeups. Thread may sometimes wake up from wait call even if no notify call has been issued. This behavior is called spurious wakeup. This can be countered by using a conditional variable (boolean flag). Put the wait() call in a while loop as long as the flag is true. So if thread wakes up from wait call due to any reasons other than Notify/NotifyAll then it encounters flag is still true and hence calls wait again. Prior to calling notify set this flag to true. In this case the boolean flag is declared as volatile.
Assume that a thread modifies the value of a shared variable, if you didn't use volatile modifier for that variable. When other threads want to read this variable's value, they don't see the updated value because they read the variable's value from the CPU's cache instead of RAM memory. This problem also known as Visibility Problem.
By declaring the shared variable volatile, all writes to the counter variable will be written back to main memory immediately. Also, all reads of the counter variable will be read directly from main memory.
public class SharedObject {
public volatile int sharedVariable = 0;
}
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. This can cause several problems which I will explain in the following sections.
Example:
Imagine a situation in which two or more threads have access to a shared object which contains a counter variable declared like this:
public class SharedObject {
public int counter = 0;
}
Imagine too, that only Thread 1 increments the counter variable, but both Thread 1 and Thread 2 may read the counter variable from time to time.
If the counter variable is not declared volatile there is no guarantee about when the value of the counter variable is written from the CPU cache back to main memory. This means, that the counter variable value in the CPU cache may not be the same as in main memory. This situation is illustrated here:
The problem with threads not seeing the latest value of a variable because it has not yet been written back to main memory by another thread, is called a "visibility" problem. The updates of one thread are not visible to other threads.
You'll need to use 'volatile' keyword, or 'synchronized' and any other concurrency control tools and techniques you might have at your disposal if you are developing a multithreaded application. Example of such application is desktop apps.
If you are developing an application that would be deployed to application server (Tomcat, JBoss AS, Glassfish, etc) you don't have to handle concurrency control yourself as it already addressed by the application server. In fact, if I remembered correctly the Java EE standard prohibit any concurrency control in servlets and EJBs, since it is part of the 'infrastructure' layer which you supposed to be freed from handling it. You only do concurrency control in such app if you're implementing singleton objects. This even already addressed if you knit your components using frameworkd like Spring.
So, in most cases of Java development where the application is a web application and using IoC framework like Spring or EJB, you wouldn't need to use 'volatile'.
volatile only guarantees that all threads, even themselves, are incrementing. For example: a counter sees the same face of the variable at the same time. It is not used instead of synchronized or atomic or other stuff, it completely makes the reads synchronized. Please do not compare it with other java keywords. As the example shows below volatile variable operations are also atomic they fail or succeed at once.
package io.netty.example.telnet;
import java.util.ArrayList;
import java.util.List;
public class Main {
public static volatile int a = 0;
public static void main(String args[]) throws InterruptedException{
List<Thread> list = new ArrayList<Thread>();
for(int i = 0 ; i<11 ;i++){
list.add(new Pojo());
}
for (Thread thread : list) {
thread.start();
}
Thread.sleep(20000);
System.out.println(a);
}
}
class Pojo extends Thread{
int a = 10001;
public void run() {
while(a-->0){
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
Main.a++;
System.out.println("a = "+Main.a);
}
}
}
Even you put volatile or not results will always differ. But if you use AtomicInteger as below results will be always same. This is same with synchronized also.
package io.netty.example.telnet;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
public class Main {
public static volatile AtomicInteger a = new AtomicInteger(0);
public static void main(String args[]) throws InterruptedException{
List<Thread> list = new ArrayList<Thread>();
for(int i = 0 ; i<11 ;i++){
list.add(new Pojo());
}
for (Thread thread : list) {
thread.start();
}
Thread.sleep(20000);
System.out.println(a.get());
}
}
class Pojo extends Thread{
int a = 10001;
public void run() {
while(a-->0){
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
Main.a.incrementAndGet();
System.out.println("a = "+Main.a);
}
}
}
While I see many good Theoretical explanations in the answers mentioned here, I am adding a practical example with an explanation here:
1.
CODE RUN WITHOUT VOLATILE USE
public class VisibilityDemonstration {
private static int sCount = 0;
public static void main(String[] args) {
new Consumer().start();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
return;
}
new Producer().start();
}
static class Consumer extends Thread {
#Override
public void run() {
int localValue = -1;
while (true) {
if (localValue != sCount) {
System.out.println("Consumer: detected count change " + sCount);
localValue = sCount;
}
if (sCount >= 5) {
break;
}
}
System.out.println("Consumer: terminating");
}
}
static class Producer extends Thread {
#Override
public void run() {
while (sCount < 5) {
int localValue = sCount;
localValue++;
System.out.println("Producer: incrementing count to " + localValue);
sCount = localValue;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
return;
}
}
System.out.println("Producer: terminating");
}
}
}
In the above code, there are two threads - Producer and Consumer.
The producer thread iterates over the loop 5 times (with a sleep of 1000 milliSecond or 1 Sec) in between. In every iteration, the producer thread increases the value of sCount variable by 1. So, the producer changes the value of sCount from 0 to 5 in all iterations
The consumer thread is in a constant loop and print whenever the value of sCount changes until the value reaches 5 where it ends.
Both the loops are started at the same time. So both the producer and consumer should print the value of sCount 5 times.
OUTPUT
Consumer: detected count change 0
Producer: incrementing count to 1
Producer: incrementing count to 2
Producer: incrementing count to 3
Producer: incrementing count to 4
Producer: incrementing count to 5
Producer: terminating
ANALYSIS
In the above program, when the producer thread updates the value of sCount, it does update the value of the variable in the main memory(memory from where every thread is going to initially read the value of variable). But the consumer thread reads the value of sCount only the first time from this main memory and then caches the value of that variable inside its own memory. So, even if the value of original sCount in main memory has been updated by the producer thread, the consumer thread is reading from its cached value which is not updated. This is called VISIBILITY PROBLEM .
2.
CODE RUN WITH VOLATILE USE
In the above code, replace the line of code where sCount is declared by the following :
private volatile static int sCount = 0;
OUTPUT
Consumer: detected count change 0
Producer: incrementing count to 1
Consumer: detected count change 1
Producer: incrementing count to 2
Consumer: detected count change 2
Producer: incrementing count to 3
Consumer: detected count change 3
Producer: incrementing count to 4
Consumer: detected count change 4
Producer: incrementing count to 5
Consumer: detected count change 5
Consumer: terminating
Producer: terminating
ANALYSIS
When we declare a variable volatile, it means that all reads and all writes to this variable or from this variable will go directly into the main memory. The values of these variables will never be cached.
As the value of the sCount variable is never cached by any thread, the consumer always reads the original value of sCount from the main memory(where it is being updated by producer thread). So, In this case the output is correct where both the threads prints the different values of sCount 5 times.
In this way, the volatile keyword solves the VISIBILITY PROBLEM .
Yes, I use it quite a lot - it can be very useful for multi-threaded code. The article you pointed to is a good one. Though there are two important things to bear in mind:
You should only use volatile if you
completely understand what it does
and how it differs to synchronized.
In many situations volatile appears,
on the surface, to be a simpler more
performant alternative to
synchronized, when often a better
understanding of volatile would make
clear that synchronized is the only
option that would work.
volatile doesn't actually work in a
lot of older JVMs, although
synchronized does. I remember seeing a document that referenced the various levels of support in different JVMs but unfortunately I can't find it now. Definitely look into it if you're using Java pre 1.5 or if you don't have control over the JVMs that your program will be running on.
Absolutely, yes. (And not just in Java, but also in C#.) There are times when you need to get or set a value that is guaranteed to be an atomic operation on your given platform, an int or boolean, for example, but do not require the overhead of thread locking. The volatile keyword allows you to ensure that when you read the value that you get the current value and not a cached value that was just made obsolete by a write on another thread.
Every thread accessing a volatile field will read its current value before continuing, instead of (potentially) using a cached value.
Only member variable can be volatile or transient.
There are two different uses of volatile keyword.
Prevents JVM from reading values from register (assume as cache), and forces its value to be read from memory.
Reduces the risk of memory in-consistency errors.
Prevents JVM from reading values in register, and forces its
value to be read from memory.
A busy flag is used to prevent a thread from continuing while the device is busy and the flag is not protected by a lock:
while (busy) {
/* do something else */
}
The testing thread will continue when another thread turns off the busy flag:
busy = 0;
However, since busy is accessed frequently in the testing thread, the JVM may optimize the test by placing the value of busy in a register, then test the contents of the register without reading the value of busy in memory before every test. The testing thread would never see busy change and the other thread would only change the value of busy in memory, resulting in deadlock. Declaring the busy flag as volatile forces its value to be read before each test.
Reduces the risk of memory consistency errors.
Using volatile variables reduces the risk of memory consistency errors, because any write to a volatile variable establishes a
"happens-before" relationship with subsequent reads of that same variable. This means that changes to a volatile variable are always visible to other threads.
The technique of reading, writing without memory consistency errors is called atomic action.
An atomic action is one that effectively happens all at once. An atomic action cannot stop in the middle: it either happens completely, or it doesn't happen at all. No side effects of an atomic action are visible until the action is complete.
Below are actions you can specify that are atomic:
Reads and writes are atomic for reference variables and for most
primitive variables (all types except long and double).
Reads and writes are atomic for all variables declared volatile
(including long and double variables).
Cheers!
Volatile does following.
1> Read and write of volatile variables by different threads are always from memory, not from thread's own cache or cpu register. So each thread always deals with the latest value.
2> When 2 different threads work with same instance or static variables in heap, one may see other's actions as out of order. See jeremy manson's blog on this. But volatile helps here.
Following fully running code shows how a number of threads can execute in predefined order and print outputs without using synchronized keyword.
thread 0 prints 0
thread 1 prints 1
thread 2 prints 2
thread 3 prints 3
thread 0 prints 0
thread 1 prints 1
thread 2 prints 2
thread 3 prints 3
thread 0 prints 0
thread 1 prints 1
thread 2 prints 2
thread 3 prints 3
To achieve this we may use the following full fledged running code.
public class Solution {
static volatile int counter = 0;
static int print = 0;
public static void main(String[] args) {
// TODO Auto-generated method stub
Thread[] ths = new Thread[4];
for (int i = 0; i < ths.length; i++) {
ths[i] = new Thread(new MyRunnable(i, ths.length));
ths[i].start();
}
}
static class MyRunnable implements Runnable {
final int thID;
final int total;
public MyRunnable(int id, int total) {
thID = id;
this.total = total;
}
#Override
public void run() {
// TODO Auto-generated method stub
while (true) {
if (thID == counter) {
System.out.println("thread " + thID + " prints " + print);
print++;
if (print == total)
print = 0;
counter++;
if (counter == total)
counter = 0;
} else {
try {
Thread.sleep(30);
} catch (InterruptedException e) {
// log it
}
}
}
}
}
}
The following github link has a readme, which gives proper explanation.
https://github.com/sankar4git/volatile_thread_ordering
From oracle documentation page, the need for volatile variable arises to fix memory consistency issues:
Using volatile variables reduces the risk of memory consistency errors, because any write to a volatile variable establishes a happens-before relationship with subsequent reads of that same variable.
This means that changes to a volatile variable are always visible to other threads. It also means that when a thread reads a volatile variable, it sees not just the latest change to the volatile, but also the side effects of the code that led up the change.
As explained in Peter Parker answer, in absence of volatile modifier, each thread's stack may have their own copy of variable. By making the variable as volatile, memory consistency issues have been fixed.
Have a look at jenkov tutorial page for better understanding.
Have a look at related SE question for some more details on volatile & use cases to use volatile:
Difference between volatile and synchronized in Java
One practical use case:
You have many threads, which need to print current time in a particular format for example : java.text.SimpleDateFormat("HH-mm-ss"). Yon can have one class, which converts current time into SimpleDateFormat and updated the variable for every one second. All other threads can simply use this volatile variable to print current time in log files.
Volatile Variables are light-weight synchronization. When visibility of latest data among all threads is requirement and atomicity can be compromised , in such situations Volatile Variables must be preferred. Read on volatile variables always return most recent write done by any thread since they are neither cached in registers nor in caches where other processors can not see. Volatile is Lock-Free. I use volatile, when scenario meets criteria as mentioned above.
volatile variable is basically used for instant update (flush) in main shared cache line once it updated, so that changes reflected to all worker threads immediately.
If you have a multithread system and these multiple threads work on some shared data, those threads will load data in their own cache. If we do not lock the resource, any change made in one thread is NOT gonna be available in another thread.
With a locking mechanism, we add read/write access to the data source. If one thread modifies the data source, that data will be stored in the main memory instead of in its cache. When others threads need this data, they will read it from the main memory. This will increase the latency dramatically.
To reduce the latency, we declare variables as volatile. It means that whenever the value of the variable is modified in any of the processors, the other threads will be forced to read it. It still has some delays but better than reading from the main memory.
Below is a very simple code to demonstrate the requirement of volatile for variable which is used to control the Thread execution from other thread (this is one scenario where volatile is required).
// Code to prove importance of 'volatile' when state of one thread is being mutated from another thread.
// Try running this class with and without 'volatile' for 'state' property of Task class.
public class VolatileTest {
public static void main(String[] a) throws Exception {
Task task = new Task();
new Thread(task).start();
Thread.sleep(500);
long stoppedOn = System.nanoTime();
task.stop(); // -----> do this to stop the thread
System.out.println("Stopping on: " + stoppedOn);
}
}
class Task implements Runnable {
// Try running with and without 'volatile' here
private volatile boolean state = true;
private int i = 0;
public void stop() {
state = false;
}
#Override
public void run() {
while(state) {
i++;
}
System.out.println(i + "> Stopped on: " + System.nanoTime());
}
}
When volatile is not used: you'll never see 'Stopped on: xxx' message even after 'Stopping on: xxx', and the program continues to run.
Stopping on: 1895303906650500
When volatile used: you'll see the 'Stopped on: xxx' immediately.
Stopping on: 1895285647980000
324565439> Stopped on: 1895285648087300
Demo: https://repl.it/repls/SilverAgonizingObjectcode
The volatile key when used with a variable, will make sure that threads reading this variable will see the same value . Now if you have multiple threads reading and writing to a variable, making the variable volatile will not be enough and data will be corrupted . Image threads have read the same value but each one has done some chages (say incremented a counter) , when writing back to the memory, data integrity is violated . That is why it is necessary to make the varible synchronized (diffrent ways are possible)
If the changes are done by 1 thread and the others need just to read this value, the volatile will be suitable.

Flush cache after multithreaded mapping writes to primitive arrays

This question relates to the latest version of Java.
I have a primitive two-dimensional array sized as below.
int[][] array = new int[numPasses][n*10]; //n threads write; during the i-th pass, the k-th thread writes to array[i] at locations k*10 to (k+1)*10-1.
//the array above is allocated at the beginning, and constantly rewritten.
During pass i, each of n producer threads writes to its own memory location in array[i], so there are no race conditions during the write process. After writing, m consumer threads read the results of this write. I do not need the consumers to access array[i] at any point in time before all the writes are done.
My first question: Would a structure like the following flush all the producer writes from cache? If not, how would one go about doing this for primitive arrays? (For technical reasons, I cannot use Atomic*Arrays.)
void flush() {//invoked after writes from all producer threads are done.
if(producerThreadID == 0) {
synchronized(array[i]) {//done at pass i.
}
}
My second question: Is there a better way to do this?
EDIT: Okay, I accept that what I want to do is essentially impossible with the empty synchronized block. Let's say that, instead of the structure above, each producer thread has access to its own pass, i.e.:
int[][] array = new int[numPasses][n*10]; //n = numPasses threads write; during the i-th pass, the i-th thread writes to all elements in array[i].
(This is Zim-Zam's suggestion.)
My (hopefully final) question: Then, would the following structure in the i-th thread ensure visibility for consumer threads after the synchronized block?
//i-th producer thread acquires lock on array[i]
void produce() {
synchronized(array[i])
//modify array[i][*] here
}
Your algorithm is probably going to create false sharing, which occurs when two threads write to nearby memory locations - if thread1 and thread2 are writing to data that shares a cache line, then the cache protocol will force thread2 to block until or re-execute after thread1 completes or vice versa. You can avoid this by using coarser grained parallelism, e.g. use one thread per pass (one thread per array) rather than one thread per array element - this way each thread is operating on its own array and there probably isn't going to be any false sharing.
I would study carefully your reasons or not using Atomics because they are exactly what you are needing.
If there is truly a problem then have you considered using sun.misc.Unsafe like the Atomics use?
Alternatively - use an array of objects holding a volatile field.
class Vint {
public volatile int i;
}
Vint[] arr = new Vint[10];
{
for (int i = 0; i < arr.length; i++) {
arr[i] = new Vint();
}
}

Categories

Resources