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

  • 相关阅读:
    三剑客
    走近SQL Server的游标
    PostSharp的AOP设计在.NET Remoting中的应用
    总结在使用VB 6.0和C#编写ActiveX控件的实践 (一)
    动态为程序指定快捷键
    为Reporting Service部署自定义程序集可能遇到的问题
    如何更改服务器名称
    如何产生固定的随机数(VBA)
    使用HTTP发送消息(消息队列技术)
    使用TransactionScope做分布式事务协调
  • 原文地址:https://www.cnblogs.com/mfrbuaa/p/5180037.html
Copyright © 2011-2022 走看看