zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    Java 构造方法总结
    Intellij IDEA使用总结
    阿里巴巴Java开发手册
    灰度发布策略
    php redis 命令合集
    php redis 常用方法
    php excel 设置单元格格式为文本格式
    php curl get post 方法的封装
    PHP 判断手机号归属地 和 运营商的免费接口
    lnmp centos7 memcache服务器端 和 memcache memcached扩展的安装
  • 原文地址:https://www.cnblogs.com/mfrbuaa/p/5180037.html
Copyright © 2011-2022 走看看