java volatile可見性的例子

一直想用代碼驗證一下使用volatile和不適用volatile對變量可見性的影響,google找到的幾個代碼示例彷佛都不太嚴密,因而寫了一個,不知道是否也不嚴密,你們幫忙看看,若是有好的驗證代碼也請提供一下。java

先給一個不使用volatile關鍵字,致使變量不可見的例子ide

public class VolatileTest {
    private int i = 0;
    private int j = 0;
    public long exceptionCount = 0;

    //線程1調用這個方法
    public void f1() {
        for(int k = 0; k < Integer.MAX_VALUE; k++) {
            i = k;
            j = i;
        }
    }

    //線程2調用這個方法
    public void f2() {
        while (true) {
            //若是線程1對i,j的修改都是可見的,就不會出現j>i的狀況了,一旦出現這種狀況就能說明線程1對i,j的修改不可見
            if(j > i) {
                exceptionCount++;
            }
        }
    }

    public static void main(String[] args) {
        final VolatileTest volatileTest = new VolatileTest();
        //線程1
        new Thread(new Runnable() {
            @Override
            public void run() {
                volatileTest.f1();
            }
        }).start();
        //線程2
        new Thread(new Runnable() {
            @Override
            public void run() {
                volatileTest.f2();
            }
        }).start();
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {

        }
        System.out.println("exceptionCount:" + volatileTest.exceptionCount);
    }
}

輸出結果爲:google

exceptionCount:6542138604spa

能夠看到exceptionCount大於0,說明線程1對變量i,j的修改對線程2不可見。線程

若是給i,j加上volatile關鍵字,則線程1對變量i,j的修改對線程2可見,下面給出代碼:code

public class VolatileTest {

    private volatile int i = 0;
    private volatile int j = 0;
    public long exceptionCount = 0;

    public void f1() {
        for(int k = 0; k < Integer.MAX_VALUE; k++) {
            i = k;
            j = i;
        }
    }

    public void f2() {
        while (true) {
            if(j > i) {
                exceptionCount++;
            }
        }
    }

    public static void main(String[] args) {
        final VolatileTest volatileTest = new VolatileTest();
        new Thread(new Runnable() {
            @Override
            public void run() {
                volatileTest.f1();
            }
        }).start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                volatileTest.f2();
            }
        }).start();
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {

        }
        System.out.println("exceptionCount:" + volatileTest.exceptionCount);
    }
}

輸出結果爲:io

exceptionCount:0class

從結果能夠看出,線程1對變量i,j的修改對線程2可見。變量

相關文章
相關標籤/搜索