If access to shared mutable data cannot be synchronized, the consequences can be dire, even if the variable is atomically readable and writable.
Let's consider a thread synchronization issue. For thread synchronization, the Java class library provides the Thread.stop method, but this method is not worth promoting because it is inherently unsafe. It would be better to use polling, such as the following program.
Copy the code code as follows:
import java.util.concurrent.TimeUnit;
public class StopThread {
/**
* @param args
*/
private static boolean stopRequested;
public static void main(String[] args)
throws InterruptedException{
Thread backgroundThread = new Thread(new Runnable() {
@Override
public void run() {
int i = 0;
while(!stopRequested){
i++;
System.out.println(i);
}
}
});
backgroundThread.start();
TimeUnit.SECONDS.sleep(1);
stopRequested = true;
}
}
You may think that after this program runs for about one second, the main thread sets stopRequested to true, causing the new thread in the background to stop. In fact, this is not the case, because the background thread cannot see the change in this value, so it will continue to loop endlessly. , this is the consequence of not synchronizing data. So let's do this synchronously.
Copy the code code as follows:
import java.util.concurrent.TimeUnit;
public class StopThread {
/**
* @param args
*/
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() {
@Override
public void run() {
int i = 0;
while(!stopRequested()){
i++;
System.out.println(i);
}
}
});
backgroundThread.start();
TimeUnit.SECONDS.sleep(1);
requestStop();
}
}
This achieves data synchronization. It is worth noting that both the write method (requestStop) and the read method (stopRequested) need to be synchronized, otherwise it is still not synchronized in the true sense.
In addition, we can use the volatile variable modifier to complete synchronization tasks more simply.
Copy the code code as follows:
import java.util.concurrent.TimeUnit;
public class StopThread {
/**
* @param args
*/
private static volatile boolean stopRequested;
public static void main(String[] args)
throws InterruptedException{
Thread backgroundThread = new Thread(new Runnable() {
@Override
public void run() {
int i = 0;
while(!stopRequested){
i++;
System.out.println(i);
}
}
});
backgroundThread.start();
TimeUnit.SECONDS.sleep(1);
stopRequested = true;
}
}