Java中Volatile的作用

Java中Volatile的作用

看了几篇博客,发现没搞懂,但是简单来说,就是在我们的多线程开发中,我们用Volatile关键字来限定某个变量或者属性时,线程在每次使用变量的时候,都会读取变量修改后的最新的值,即Volatile关键字保证了变量的可见性。但是,并不能保证变量的原子性,这就导致了volatile关键字的误用在并发的时候结果与我们的预期会是不一样的,可以看下如下代码:

package com.wrh.firstpro;

public class TestVolatile {

    public volatile static int count = 0;

    public static void inc() {

        //这里延迟1毫秒,使得结果明显
        try {
            Thread.sleep(1);
        } catch (InterruptedException e) {
        }

        count++;
    }

    public static void main(String[] args) {

        //同时启动1000个线程,去进行i++计算,看看实际结果

        for (int i = 0; i < 1000; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    TestVolatile.inc();
                }
            }).start();
        }

        //这里我们休眠10秒钟,使得我们输出语句执行的时候所有子线程均已经执行完成
        try {
            Thread.sleep(10*1000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        //这里每次运行的值都有可能不同,可能为1000
        System.out.println("运行结果:Counter.count=" + TestVolatile.count);
    }
}

上面出现的结果每次运行的值都有可能不同,可能为1000,出现的原因:

对于可见性,Java提供了volatile关键字来保证可见性。
当一个共享变量被volatile修饰时,它会保证修改的值会立即被更新到主存,当有其他线程需要读取时,它会去内存中读取新值。
而普通的共享变量不能保证可见性,因为普通共享变量被修改之后,什么时候被写入主存是不确定的,当其他线程去读取时,此时内存中可能还是原来的旧值,因此无法保证可见性。
另外,通过synchronized和Lock也能够保证可见性,synchronized和Lock能保证同一时刻只有一个线程获取锁然后执行同步代码,并且在释放锁之前会将对变量的修改刷新到主存当中。因此可以保证可见性。

但是:volatile不能保证对变量的操作是原子性,这就是导致上面的根本原因。
具体讲解可以看这篇博客:http://www.cnblogs.com/dolphin0520/p/3920373.html(我看的几篇博客中讲解volatile关键字讲解的最清晰的了)
还可以看这里:http://www.cnblogs.com/aigongsi/archive/2012/04/01/2429166.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值