DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones AWS Cloud
by AWS Developer Relations
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones
AWS Cloud
by AWS Developer Relations
  1. DZone
  2. Software Design and Architecture
  3. Integration
  4. Threading stories: Why volatile matters

Threading stories: Why volatile matters

Niklas Schlimm user avatar by
Niklas Schlimm
·
Oct. 25, 11 · Interview
Like (0)
Save
Tweet
Share
8.74K Views

Join the DZone community and get the full member experience.

Join For Free

Many years ago when I learned Java (in 2000) I was not so concerned about multithreading. In particular I wasn't concerned about the volatile modifier. I don't know why, but I never had problems without volatile, so maybe I thought it could not be so relevant. I've suddenly changed my mind when I first analyzed a wierd behaviour of an application that only existed when the application was deployed to a server JVM. Todays JVMs make a lot magic stuff to optimize runtime performance on server applications. In this blog I show you an example to get fimiliar with problems that arrize in multithreaded applications, when you don't recognize the importance of understanding how Java treats shared data in multithreaded programs.

This code snippet demonstrates why understanding volatile is important. Here is the code that you can use to play around. Notice in line 8 the expired variable is declared volatile:

import java.util.Timer;
import java.util.TimerTask;

public class VolatileExample {

 private volatile boolean expired;
 private long counter = 0;
 private Object mutext = new Object();

 @Override
 public Object[] execute(Object... arguments) {
  synchronized (mutext) {
   expired = false;
   final Timer timer = new Timer();
   timer.schedule(new TimerTask() {
    public void run() {
     expired = true;
     System.out.println("Timer interrupted main thread ...");
     timer.cancel();
    }
   }, 1000);
   while (!expired) {
    counter++; // do some work
   }
   System.out.println("Main thread was interrupted by timer ...");
  };
  return new Object[] { counter, expired };
 }

 private class Worker implements Runnable {
  @Override
  public void run() {
   while (!Thread.currentThread().isInterrupted()) {
    execute();
   }
  }
 }

 @SuppressWarnings("static-access")
 public static void main(String[] args) throws InterruptedException {
  VolatileExample volatileExample = new VolatileExample();
  Thread thread1 = new Thread(volatileExample.new Worker(), "Worker-1");
  Thread thread2 = new Thread(volatileExample.new Worker(), "Worker-2");
  thread1.start();
  thread2.start();
  Thread.currentThread().sleep(60000);
  thread1.interrupt();
  thread2.interrupt();
 }
}

 

Start that with Hotspot VM with -server option set. What you'll get is the following expected output:

Timer interrupted main thread ...
Main thread was interrupted by timer ...
Timer interrupted main thread ...
Main thread was interrupted by timer ...
Timer interrupted main thread ...
Main thread was interrupted by timer ...
Timer interrupted main thread ...
Main thread was interrupted by timer ...
Timer interrupted main thread ...
Main thread was interrupted by timer ...

 

Now take out the volatile in line 8 above and restart, again with -server option set. What you should get is the following output:

Timer interrupted main thread ...

What happened? The Timer thread sets the expired flag to true but the main thread does not see the change. This is exactly what volatile is all about: it ensures that threads share the actual value of a specific variable. If you declare a variable as volatile all threads read that specific value from the memory heap. In the described example the timer thread set the expired value within the thread and this update was not reflected in the memory heap! Notice, that I cancel the timer thread when I set the expired variable to true. This causes the timer thread to die immediately after the run()-method is passed. However, it does not make an effort to update the memory heap before it terminates. The change to the variable is lost.

Next: now restart the code again without the volatile modifier. This time you set the -client JVM option (which is the default mode on Windows). The result is the following:

Timer interrupted main thread ...
Main thread was interrupted by timer ...
Timer interrupted main thread ...
Main thread was interrupted by timer ...
Timer interrupted main thread ...
Main thread was interrupted by timer ...
Timer interrupted main thread ...
Main thread was interrupted by timer ...
Timer interrupted main thread ...
Main thread was interrupted by timer ...

 

In the client mode the JVM obviously behaves different and does not optimize so aggressively like in server mode. So even if you missed out the volatile modifier, you may not necessarily see an error during development. The JVM options influence the way how strict the JVM optimzes your code. Without volatile it is not garanteed that data changes made by the timer thread are visible to the main thread. But in this case for instance everything still works OK in client mode, which shows that the result of your program relies on the JVM options set. 

From http://niklasschlimm.blogspot.com/2011/10/threading-stories-why-volatile-matters.html

Java (programming language) Threading

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • How To Use Java Event Listeners in Selenium WebDriver
  • Microservices 101: Transactional Outbox and Inbox
  • Unlock the Power of Terragrunt’s Hierarchy
  • Automated Testing With Jasmine Framework and Selenium

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: