volatile 關鍵字的兩層語義
java
一旦一個共享變量(類的成員變量、類的靜態成員變量)被 volatile 修飾以後,那麼就具有了兩層語義:
1)保證了不一樣線程對這個變量進行操做時的 可見性,即一個線程修改了某個變量的值,這新值對其餘線程來講是當即可見的。
2)禁止進行 指令重排序。
方式一:變量不使用 volatile 修飾ide
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 修飾this
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; } }
運行結果
方式一:線程不會結束
線程
方式二:線程會結束
code
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); } }