Java Reference
In-Depth Information
You can declare only a class member variable (instance or
static
fields) as
volatile
. You cannot declare a local
variable as
volatile
because a local variable is always private to the thread, which is never shared with other threads.
You cannot declare a
volatile
variable
final
because the
volatile
keyword is used with a variable that changes.
You can use a
volatile
variable to stop a thread by using the variable's value as a flag. If the flag is set, the thread
can keep running. If another thread clears the flag, the thread should stop. Since two threads share the flag, you need
to declare it
volatile
, so that on every read the thread will get its updated value from the main memory.
Listing 6-24 demonstrates the use of a
volatile
variable. If the
keepRunning
variable is not declared
volatile
,
the JVM is free to run the while-loop in the
run()
method forever, as the initial value of
keepRunning
is set to
true
and a thread can cache this value in its working memory. Since the
keepRunning
variable is declared
volatile
, the
JVM will read its value from the main memory every time it is used. When another thread updates the
keepRunning
variable's value to
false
using the
stopThread()
method, the next iteration of the while-loop will read its updated
value and stop the loop. Your program may work the same way as in Listing 6-23 even if you do not declare the
keepRunning
as
volatile
. However, according to the JVM specification, this behavior is not guaranteed. If the JVM
specification is implemented correctly, using a
volatile
variable in this way ensures the correct behavior for
your program.
Listing 6-24.
Using a volatile Variable in a Multi-Threaded Program
// VolatileVariable.java
package com.jdojo.threads;
public class VolatileVariable extends Thread {
private volatile boolean keepRunning = true;
public void run() {
System.out.println("Thread started...");
// keepRunning is volatile. So, for every read, the thread reads its
// latest value from the main memory
while (keepRunning) {
try {
System.out.println("Going to sleep ...");
Thread.sleep(1000);
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Thread stopped...");
}
public void stopThread() {
this.keepRunning = false;
}
public static void main(String[] args) {
// Create the thread
VolatileVariable vv = new VolatileVariable();
// Start the thread
vv.start();