Sunday, May 15, 2016

Java Threading - Usage of volatile key word.

Threading is important when considering the obligation of work in a program, handle more than one event at a time. But if it is not used in proper way it can lead to some problems as well.

Data being cached is a problem that can encounter in some scenarios. Lets take a look at one.

Consider the following java class

class Processor extends Thread{
 private boolean running =true;
 public void run(){
  while(running){
   System.out.println("hello ");
   try{
    Thread.sleep(100);
   }catch(InterruptedException e){
    e.printStackTrace();
   }
  }
 }
 public void shutDown(){
  running = false;
 }
}
That code is executed as follows

public class App {
public static void main(String args[]){
Processor proc1 = new Processor();
  
 proc1.start();
 
 Scanner scanner = new Scanner(System.in);
 scanner.nextLine();
 
 proc1.shutDown();
 }
}
There are three main things that happen in this code.
1. It starts a separate thread and run the code in Processor class. so that tread will check the running variable and it will print Hello while running is true.
2. At the same time main thread will execute Scanner scanner = new Scanner(System.in); and listen to user inputs.
3. If user enter something it will change the running variable into false by executing proc1.shutDown();

When running becomes false the other thread will stop printing Hello. That is what we expect. But it may not happen sometimes. Lest see why.

When code is running in a separate thread sometimes that thread doesn't expect other threads to modify its data. So some variables relevant to that thread can be cached for optimization of execution of code. In this case running variable can be cashed and thread printing Hello may only look at that cached version of variable.But main thread can change the original variable after a user input. But printing Hello won't be stopped because thread that prints Hello is checking a cached running variable.

In order to prevent that kind of scenario in java volatile keyword can be used when declaring a variable.
private volatile boolean running =true;
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.

So after using volatile keyword when declaring a variable, thread that check the variable always see an updated latest version of variable. :)

Here is a nice article about some patterns for using volatile variables effectively

Note: The cache is there to reduce the number of times the CPU would stall waiting for a memory request to be fulfilled (avoiding the memory latency), and as a second effect, possibly to reduce the overall amount of data that needs to be transfered (preserving memory bandwidth).

No comments:

Post a Comment

Optimize you working enviorenment : Single command to create & move to a directory in linux (C Shell, Bash)

Usually move to a directory just after creating is bit of a anxious task specially if the directory name is too long. mkdir long-name-of...