一、为什么要有volatilekeyword

预计非常多java刚開始学习的人都被volatile这个keyword迷惑过。尽管网上有非常多讨论volatile的文章,但它们有的过于讲述底层原理,而没有说明其应用场景,让刚開始学习的人看后还是一头雾水;有的过于使用类比解说。造成了一定的错误。这种文章更害人。以下,小弟试着分析下volatilekeyword的作用及使用方法。希望能给大家带来一定的启示。文中错误之处,请各位大神指正。

我们知道,在多线程编程中,多个线程在訪问共享变量时,必须进行必要的同步,否则非常可能产生错误。synchronizedkeyword能够用来提供这样的同步。该keyword主要将方法或者代码块设定为同步的方法或者同步的代码块。

这样的同步能够提供例如以下两个保证:

1、原子性。无论这种方法或者代码块被多少线程訪问。方法和代码块中的语句仅仅能作为一个总体运行,即当一个线程訪问一个同步方法时,仅仅有当方法运行完时,其它线程才干运行该方法。简单讲,就是一个线程一个线程来,并且必须所有运行完同步方法或代码块中的语句。

2、内存可见性。

这指的是一个线程在同步方法或者代码块中对共享变量做的不论什么改变,对随后的其它线程都是可见的。

这样的同步机制就像是一套严整的西装,非常标准,但就是穿起来有点别扭,开销也大。有时用起来不是非常方便,比方,在程序中有一个状态变量。被多个线程读取,我们仅仅要求每一个线程读取到的值都是最新值,并依据最新状态採取不同的操作。这样的情况下,java为我们提供了一个轻量级的解决方式,就是使用volatile。

二、volatilekeyword的作用是什么

volatile的英文意思是“易变的。不稳定的;(液体或油)易挥发的;爆炸性的;快活的。轻快的”。可见,单从字面上理解,volatile应该用在易变、不稳定的变量上。其实,确实如此,这个keyword的作用就是告诉编译器,凡是被该keyword声明的变量都是易变的、不稳定的。

所以不要试图对该变量使用缓存等优化机制,而应当每次都从它的内存地址中去读取值。

使用volatile标记的变量在读取或写入时不须要使用锁,这将降低产生死锁的概率,使代码保持简洁。

请注意。这里仅仅是说每次读取volatile的变量时都要从它的内存地址中读取。并没有说每次改动完volatile的变量后都要立马将它的值写回内存。也就是说volatile仅仅提供了内存可见性。而没有提供原子性。

三、什么时候使用volatilekeyword

知道了volatile的作用,我们也就知道了它应该用在哪些地方。

非常显然。最好是那种仅仅有一个线程改动变量。多个线程读取该变量的地方。

也就是对内存可见性要求高,而对原子性要求低的地方。

举个样例,我们写游戏时。常常须要定义一个游戏的状态变量,并在主线程中依据不同条件改动它。为了提高游戏执行效率,我们通常并发用多个线程处理程序数据。这些线程都要訪问游戏的状态变量,才干依据游戏状态进行对应的操作。这个时候用volatile就再合适只是了。

具体解释java中的volatilekeyword的更多相关文章

  1. 全面解释java中StringBuilder、StringBuffer、String类之间的关系

    StringBuilder.StringBuffer.String类之间的关系 java中String.StringBuffer.StringBuilder是编程中经常使用的字符串类,在上一篇博文中我 ...

  2. 用画小狗的方法来解释Java中的值传递

    在开始看我画小狗之前,咱们先来看道很简单的题目: 下面程序的输出是什么? Dog myDog = new Dog("旺财"); changeName(myDog); System. ...

  3. java中基本输入输出流的解释(flush方法的使用)

    转自:http://fsz521job.itpub.net/post/5606/34827 网络程序的很大一部分是简单的输入输出,即从一个系统向另一个系统移动字节.字节就是字节,在很大程度上,读服务器 ...

  4. Java中JNI的使用详解第二篇:JNIEnv类型和jobject类型的解释

    上一篇说的是一个简单的应用,说明JNI是怎么工作的,这一篇主要来说一下,那个本地方法sayHello的参数的说明,以及其中方法的使用 首先来看一下C++中的sayHello方法的实现: JNIEXPO ...

  5. Java进阶(十五)Java中设置session的详细解释

    Java中设置session的详细解释 简单通俗的讲session就是象一个临时的容器,用来存放临时的东西.从你登陆开始就保存在session里,当然你可以自己设置它的有效时间和页面,举个简单的例子: ...

  6. Java中名词的解释

    在上一篇中说到了Java的四大特性,里面出现了很多名次,包括以后学习Java中也会出现很多常用到的名次,对初学者来说可能不知道是什么意思,或者是对这些刺耳的理解不是特别透彻,这里我就我自己的理解来解释 ...

  7. Java中的final具体解释以及用途实战

    浅析Java中的finalkeyword 谈到finalkeyword,想必非常多人都不陌生.在使用匿名内部类的时候可能会经经常使用到finalkeyword. 另外.Java中的String类就是一 ...

  8. 关于高淇JAVA中SORM总结学习笔记详细个人解释

    代码来源于高淇JAVA教学视频 谢谢高淇老师的教学. 因为自己在学习的过程中发现了很多困难点,总结下希望对自己接下来学框架提升.给像我一样得初学者方便. SORM框架是一个简单的ORM,关系对象映射, ...

  9. 【Java面试题】解释内存中的栈(stack)、堆(heap)和静态存储区的用法

    Java面试题:解释内存中的栈(stack).堆(heap)和静态存储区的用法 堆区: 专门用来保存对象的实例(new 创建的对象和数组),实际上也只是保存对象实例的属性值,属性的类型和对象本身的类型 ...

随机推荐

  1. 国内各视频网站android pad客户端支持分辨率情况初步统计

    视频网站名称 800*600 1024*600 1280*800 其他 国际化   备注 优酷 支持 支持 支持 支持 不支持     土豆网 没有pad版的 没有pad版的 没有pad版的 支持 不 ...

  2. Linux 学习 step by step (1)

    做为一个技术小菜的android的程序员,做应用层的app觉得没有什么意思,于是像多学点android底层的知识.最近在看<Android 技术内幕(系统卷)> . 我打开书的第一张,便花 ...

  3. LA 4728 Square ,旋转卡壳法求多边形的直径

    给出一些正方形.让你求这些正方形顶点之间的最大距离的平方. //返回点集直径的平方 int diameter2(vector<Point> & points) { vector&l ...

  4. 用C语言获取任意文件的长度(可能大于2GB)

    用C语言获取文件长度的常见思路是: 打开文件后用 fseek() 函数把文件位置指针移动到文件的末尾,用 ftell() 获得这时位置指针距文件头的字节数,这个字节数就是文件的长度.但是这样做也会受到 ...

  5. 在Linux上安装Chef工作站

    导读 Chef是一个IT基础设施自动化软件,它可以管理你组织中所有的服务器和网络设备.当我们想与Chef服务器.任何物理节点(服务器.网络设备等)的基础设施进行交互时,我们需要一个Chef工作站.本教 ...

  6. 数据需求统计常用awk命令

    原文:http://www.5iops.com/html/2013/script_0418/267.html 1.将时间转换为时间戳 select unix_timestamp('2009-10-26 ...

  7. 浅谈Java两种并发类型——计算密集型与IO密集型

    转载:https://blog.csdn.net/u013070853/article/details/49304099 核心是可以分别独立运行程序指令的计算单元.线程是操作系统能够进行运算调度的最小 ...

  8. 嵌入式web服务器-thttpd

    交叉编译thttpd http://lakie.blog.163.com/blog/static/45185220201162910432330/ thttpd安装与调试 http://blog.cs ...

  9. ubuntu 安装 codelite

    http://www.linuxidc.com/Linux/2013-06/85332.htm Ubuntu 12.04下为codelite增添更新源 1.获取codelite的公钥 sudo apt ...

  10. PL/SQL之DBMS_SQL程序包使用(1)(学习笔记)

    dbms_sql程序包dbms_sql程序包是系统提供给我们的另一种使用动态SQL的方法:使用DBMS_SQL包实现动态的SQL的步骤如下:1.将要执行的SQL语句或者一个语句放到一个字符串变量中2. ...