JAVA并发编程之volatile关键字

JAVA多线程编程之volatile关键字


volatile

修饰变量,直接存取原始内存的值;禁止指令重排序
volatile 百度百科

volatile可以保证内存的可见性

1.了解下线程内存和主内存的关系

Java线程内存和主内存图例

如图,每个线程都有自己单独的内存空间,储存着从主内存拷贝进来的副本,如果变量是共享变量(多个线程会用到),那么就会存在线程A和线程B中变量A的值不相同的情况。

2.volatile强制直接从原始内存中存取

int a = 变量A

此时变量A会直接从主内存中加载

变量A++

此时变量A会直接写回主内存

public class VolatileTest {
    //如果有volatile关键字程序会立即退出
    //如果没有volatile关键字,程序可能永远不会退出
    static volatile boolean isStop = false;

    /*boolean isStop = false;*/
    public void test() {
        Thread t = new Thread() {
            public void run() {
                while (!isStop) ;
            }
        };
        t.start();
    }

    public static void main(String args[]) throws InterruptedException {
        for (int i = 0; i < 25; i++) {
            new VolatileTest2().test();
        }
        isStop = true;
    }
}

运行上面的代码看看结果

3.volatile能够保证有序性(禁止指令重排序)

在Java内存模型中,允许编译器和处理器对指令进行重排序,但是重排序过程不会影响到单线程程序的执行,却会影响到多线程并发执行的正确性。

/**
 * 一个简单的展示Happen-Before的例子.
 * 这里有两个共享变量:a和flag,初始值分别为0和false.在ThreadA中先给a=1,然后flag=true.
 * 如果按照有序的话,那么在ThreadB中如果if(flag)成功的话,则应该a=1,而a=a*1之后a仍然为1,下方的if(a==0)应该永远不会为真,永远不会打印.
 * 但实际情况是:在试验100次的情况下会出现0次或几次的打印结果,而试验1000次结果更明显,有十几次打印.
 */
public class SimpleHappenBefore {
    /** 这是一个验证结果的变量 */
    private static int a=0;
    /** 这是一个标志位 */
    private static boolean flag=false;
    public static void main(String[] args) throws InterruptedException {
        //由于多线程情况下未必会试出重排序的结论,所以多试一些次
        for(int i=0;i<1000;i++){
            ThreadA threadA=new ThreadA();
            ThreadB threadB=new ThreadB();
            threadA.start();
            threadB.start();
            //这里等待线程结束后,重置共享变量,以使验证结果的工作变得简单些.
            threadA.join();
            threadB.join();
            a=0;
            flag=false;
        }
    }
    static class ThreadA extends Thread{
        public void run(){
        a=1;
        flag=true;
        }
    }
    static class ThreadB extends Thread{
        public void run(){
            if(flag){
            a=a*1;
            }
            if(a==0){
            System.out.println("ha,a==0");
            }
        }
    }
}

上段代码引用博客[http://my.oschina.net/004/blog/222069?fromerr=ER2mp62C]

我的个人博客,有空来坐坐

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值