一、为什么要有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 Notification实现推送消息过程中接受到消息端有声音及震动及亮屏提示

    在Android Notification状态栏通知一文中,简单实现了消息的推送效果,这里就接着上文说一下,当用户接受到消息时的提示效果 // 5-增加震动及声音及亮屏 notification.de ...

  2. CI框架入门中的简单MVC样例

    最简单的CI模型: 注意:模型须要用到数据库 配置文件在appcation/config.php 这里我们要用到数据库,须要将databases.php中的 相关參数填写一下,详细不再赘述. 直接进入 ...

  3. Inner Classes with TypeScript

    原文:https://blog.oio.de/2014/03/21/inner-classes-typescript/ b.ts class Foo { sex:string; say(){ new ...

  4. Transformer中引用iqd作为数据源的时候数据预览出现乱码

    在cognos开发利用transform建模的过程中导入iqd数据源预览乱码问题,下面先描述一下环境 操作系统版本: [root@enfo212 ~]# cat /proc/version Linux ...

  5. hiberante 二级缓存设置

    <?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.spr ...

  6. Visual Studio使用中的问题

    1.后台断点调试,一到断点的时候就VS已停止 原因:安装插件问题,我的由于安装了" .NET Reflector Visual Studio Extension "插件 解决办法: ...

  7. 关于Haxe3新特性“内联构造方法”的解释

    学习过C/C++的童鞋们应该了解inline即内联机制的意义,Haxe语言也很好的支持内联机制,让开发者可以自己在空间效率和时间效率上进行取舍. 从Haxe3开始,构造方法也可以使用inline关键字 ...

  8. php之快速入门学习-14(php-for循环)

    PHP 循环 - For 循环 循环执行代码块指定的次数,或者当指定的条件为真时循环执行代码块. for 循环 for 循环用于您预先知道脚本需要运行的次数的情况. 语法 for (初始值; 条件; ...

  9. libcurl库进行http通讯-开篇

    从今天開始介绍一些经常使用的库. 首先就来写一写关于libcurl库. libcurl主要功能就是用不同的协议连接和沟通不同的server~也就是相当封装了的sockPHP 支持libcurl(同意你 ...

  10. java—(2)maven基本命令

    均在含pom.xml文件的路径下执行 maven命令执行是按阶段执行的.如执行mvn package.则实际上已经执行了例如以下命令: watermark/2/text/aHR0cDovL2Jsb2c ...