volatile是否可以使普通变量对于不同的线程可见?

问题描述 投票:0回答:1
public class TestMemVisbility {
static  volatile int flag;
static int[] arr=new int[100000];
public static void main(String[] args) {
    new Thread(new Runnable() {
        @Override
        public void run() {
            while(flag==0) ;
            for(int i=0;i<100000;i++)
                if(arr[i]!=i) System.out.println("false");
        }
    }).start();
    new Thread(new Runnable() {
        @Override
        public void run() {
            flag=0;
            for(int i=0;i<100000;i++)
                arr[i]=i;
            flag=1;
        }

    }).start();
}

}

据我所知,volatile只能使自身(在它之前不是普通的变量)对于其他线程可见。所以我要对其进行测试,但什么也没打印。

java locking volatile cas barrier
1个回答
0
投票

我认为您的代码存在一些问题

public class TestMemVisbility {
static  volatile int flag;
static int[] arr=new int[100000];
public static void main(String[] args) {
    new Thread(new Runnable() {
        @Override
        public void run() {
            while(flag==0) ;  // this may hold the CPU in forever and never give the second thread a chance to run.
            for(int i=0;i<100000;i++)
                if(arr[i]!=i) System.out.println("false");
        }
    }).start();
    new Thread(new Runnable() {
        @Override
        public void run() { //could nerver be able to run, or maybe have too wait thread 1 to finish, before its turn
            flag=0;
            for(int i=0;i<100000;i++)
                arr[i]=i;
            flag=1;
        }

    }).start();

    //your main thread is finished too early for the other two threads to run.
}

[您想了解volatile的工作原理,可以对代码进行一些调整:

new Thread(new Runnable() {
            @Override
            public void run() {
                for(int i=0;i<100;i++) {
                    System.out.println("1");
                    if (flag == 1 && arr[i] == i) { 
                        System.out.println("false"); //here you know flag is changed
                    }
                    try {
                        Thread.sleep(20); //release the CPU resources if it running first
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                flag=0;
                for(int i=0;i<100;i++) {
                    arr[i] = i;
                    System.out.println("2");
                }
                flag=1;
            }

        }).start();

        try {
            Thread.sleep(1000);  // main thread hold til give other two threads time to finish
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
© www.soinside.com 2019 - 2024. All rights reserved.