In the book Effective Java:
public class StopThread {
private static boolean stopRequested;
public static void main(String[] args) throws InterruptedException {
Thread backgroundThread = new Thread(new Runnable() {
public void run() {
int i = 0;
while (!stopRequested)
i++;
}
});
backgroundThread.start();
TimeUnit.SECONDS.sleep(1);
stopRequested = true;
}
}
backgroundThread does not stop after one second. Since the rise, optimization in the JVM, the HotSpot server VM does.
You can view this in the next section:
Why does HotSpot optimize the following using a lift? .
Optimization is performed as follows:
if (!done)
while (true)
i++;
There are two ways to fix the problem.
1. Use volatile
private static volatile boolean stopRequested;
The function of volatiles is to prohibit lifting - it ensures that any stream that reads the field will see the last recorded value
2. Use synchronized
public class StopThread {
private static boolean stopRequested;
private static synchronized void requestStop() {
stopRequested = true;
}
private static synchronized boolean stopRequested() {
return stopRequested;
}
public static void main(String[] args)
throws InterruptedException {
Thread backgroundThread = new Thread(new Runnable() {
public void run() {
int i = 0;
while (!stopRequested())
i++;
}
});
backgroundThread.start();
TimeUnit.SECONDS.sleep(1);
requestStop();
}
}
The above code is right in the book "Effective Java", its equivalent, which is used volatilefor decoration stopRequested.
private static boolean stopRequested() {
return stopRequested;
}
synchronized, .
, hoisting, synchronized.
?