volatile 關鍵字的兩層語義
一旦一個共享變量(類的成員變量、類的靜态成員變量)被 volatile 修飾之後,那麼就具備了兩層語義:
1)保證了不同線程對這個變量進行操作時的
可見性,即一個線程修改了某個變量的值,這新值對其他線程來說是立即可見的。
2)禁止進行
指令重排序 。
方式一:變量不使用 volatile 修飾
public class VolatileTest extends Thread {
private static boolean flag = false;
public void run() {
while (!flag) ;
}
public static void main(String[] args) throws Exception {
new VolatileTest().start();
Thread.sleep(2000);
flag = true;
}
}
方式二:變量使用 volatile 修飾
public class VolatileTest extends Thread {
private static volatile boolean flag = false;
public void run() {
while (!flag) ;
}
public static void main(String[] args) throws Exception {
new VolatileTest().start();
Thread.sleep(2000);
flag = true;
}
}
運作結果
方式一:線程不會結束
方式二:線程會結束
public class TestMain {
public static volatile boolean flag = true;
public static void main(String[] args) throws InterruptedException {
new Thread(new Runnable() {
@Override
public void run() {
while (flag) {
}
System.out.println(Thread.currentThread().getName() + "線程停止,死循環被打開");
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
flag = false;
System.out.println(Thread.currentThread().getName() + "修改 flag 為" + flag);
}
}).start();
Thread.sleep(Integer.MAX_VALUE);
}
}
public class RunThread extends Thread {
/** volatile */
private volatile boolean isRunning = true;
private void setRunning(boolean isRunning) {
this.isRunning = isRunning;
}
public void run() {
System.out.println("進入 run() 方法中...");
while (isRunning == true) {
// doSomething()
}
System.out.println("線程結束了...");
}
public static void main(String[] args) throws InterruptedException {
RunThread myThread = new RunThread();
myThread.start();
Thread.sleep(3000);
myThread.setRunning(false);
System.out.println("isRunning 的值已經設定為了 false");
Thread.sleep(1000);
System.out.println(myThread.isRunning);
}
}
public class RunThread extends Thread {
/** volatile */
private boolean isRunning = true;
private void setRunning(boolean isRunning) {
this.isRunning = isRunning;
}
public void run() {
System.out.println("進入 run() 方法中...");
while (isRunning == true) {
// doSomething()
}
System.out.println("線程結束了...");
}
public static void main(String[] args) throws InterruptedException {
RunThread myThread = new RunThread();
myThread.start();
Thread.sleep(3000);
myThread.setRunning(false);
System.out.println("isRunning 的值已經設定為了 false");
Thread.sleep(1000);
System.out.println(myThread.isRunning);
}
}
轉載于:https://www.cnblogs.com/hglibin/p/9942486.html