具体解释java中的volatilekeyword

一、为什么要有volatilekeyword

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

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

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

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

2、内存可见性。

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

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

二、volatilekeyword的作用是什么

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

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

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

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

三、什么时候使用volatilekeyword

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

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

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

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

时间: 2024-12-08 16:21:20

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

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

http://www.jb51.net/article/33398.htm String的值是不可变的,这就导致每次对String的操作都会生成新的String对象,不仅效率低下,而且大量浪费有限的内存空间,StringBuffer是可变类,和线程安全的字符串操作类,任何对它指向的字符串的操作都不会产生新的对象,StringBuffer和StringBuilder类功能基本相似 1. String 类  String的值是不可变的,这就导致每次对String的操作都会生成新的String对象,不

用生活中的例子解释java中的接口

阅读本文前置条件 需要你掌握接口和抽象类的基本定义与区别. 小例子 抽象类 一说到公司的财务人员,大家都知道他的行政职能是什么. 这个职位就是抽象类.其中那套财政处理流程就是抽象类中具体的方法. 这个抽象类(职位)并不能直接处理财务问题,只是规定了在这个职位上的人应该遵循这套办事流程. 具体类 每个职员都有各自不同的特性,比如工资差异,回家的方式等. 这个人员就是具体的类,继承自这个财务职位,但是有各自差异的方法. 这个具体类(财务人员)是直接处理财务问题,是一个可以产生活动的类(人员).其中哪

Java中serialVersionUID的解释

Java中serialVersionUID的解释 serialVersionUID作用:        序列化时为了保持版本的兼容性,即在版本升级时反序列化仍保持对象的唯一性. 有两种生成方式: 一个是默认的1L,比如:private static final long serialVersionUID = 1L; 一个是根据类名.接口名.成员方法及属性等来生成一个64位的哈希字段,比如:        private static final   long     serialVersionU

java中的容器解释

解释一:容器(Container)Spring 提供容器功能,容器可以管理对象的生命周期.对象与对象之间的依赖关系,您可以使用一个配置文件(通常是XML),在上面定义好对象的名称.如何产生(Prototype 方式或Singleton 方式).哪个对象产生之后必须设定成为某个对象的属性等,在启动容器之后,所有的对象都可以直接取用,不用编写任何一行程序代码来产生对象,或是建立对象与对象之间的依赖关系.换个更直白点的说明方式:容器是一个Java 所编写的程序,原先必须自行编写程序以管理对象关系,现在

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

上一篇说的是一个简单的应用,说明JNI是怎么工作的,这一篇主要来说一下,那个本地方法sayHello的参数的说明,以及其中方法的使用 首先来看一下C++中的sayHello方法的实现: [cpp] view plaincopy JNIEXPORT void JNICALL Java_com_jni_demo_JNIDemo_sayHello (JNIEnv * env, jobject obj) { cout<<"Hello World"<<endl; } 对于

Java中对象、对象引用、堆、栈、值传递以及引用传递的详细解释

Java中对象.对象引用.堆.栈.值传递以及引用传递的详细解释 1.对象和对象引用的区别: (1).对象: 万物皆对象.对象是类的实例.在Java中new是用来在堆上创建对象用的.一个对象可以被多个引用所指向. (2).对象引用: 类似于C++中的地址.通过对象引用可以找到对象.一个引用可以指向多个对象.操纵的标识符实际上是指向对象的引用. 就像:对象存放在屋子里,对象的引用就相当于屋子的钥匙. 2.值传递和引用传递的区别: (1).值传递:传递的是值的拷贝.也就是说传递后就不互相关了. (2)

Java中的ClassLoader详细解释

java中的.java文件经过编译以后,就会生成类文件.class文件.class文件是以二进制字节码存放在硬盘中的.当我们需要使用或加载Java文件到JVM中的时候,会从硬盘中读取字节码的class文件,然后通过类加载器将class文件加载到JVM中.也就是说,所有的Java文件都是通过类加载器加载到JVM中的.当然类加载器也是一个Java文件.那么第一个类加载器又是如何加载到JVM中的呢?在启动JVM的时候,会调运一个本地方法findBootStrapClass方法加载最初始的那个Class

简述JDBC原理 + 在JAVA中异常是什么 + throws 与 throw 区别 + 简单解释以下JAVA中的多态

JDBC原理: 加:加载驱动 链:创建连接 预:创建预编译 执:执行SQL语句(查询需要处理结果级) 释:关闭链接: DBC中定义了一些接口:  1.驱动管理:  DriverManager  2.连接接口  Connection  DatabasemetaData  3.语句对象接口  Statement  PreparedStatement  CallableStatement  4.结果集接口  ResultSet  ResultSetMetaData JDBC只定义接口,具体实现由各个数

转!!Java中关于Null的9个解释(Java Null详解)

对于Java程序员来说,null是令人头痛的东西.时常会受到空指针异常(NPE)的骚扰.连Java的发明者都承认这是他的一项巨大失误.Java为什么要保留null呢?null出现有一段时间了,并且我认为Java发明者知道null与它解决的问题相比带来了更多的麻烦,但是null仍然陪伴着Java. 我越发感到惊奇,因为java的设计原理是为了简化事情,那就是为什么没有浪费时间在指针.操作符重载.多继承实现的原因,null却与此正好相反.好吧,我真的不知道这个问题的答案,我知道的是不管null被Ja