原创作品,可以转载,但是请标注出处地址:http://www.cnblogs.com/V1haoge/p/7833881.html

  据说,volatile是java语言中最轻量级的并发控制方式。

  volatile可以保证变量的可见性,指的是什么呢?

  可见性指的是在某一线程中对变量进行修改之后,其他线程可以立即发现并使用这个修改(一个线程的修改对其他线程可见)。

  可见性的实现方式:volatile对java内存模型中主内存和工作内存交互方式的控制。volatile确保一个线程对其修饰的变量的更改立即写入到主内存,同时确保每一次针对其修饰变量的读取操作直接从主内存中获取(即volatile强制将assign赋值操作和store、write操作绑定在一起,将use使用操作强制和read、load操作绑定在一起,这样assign之后必须执行store、write操作,use操作之前必须先执行read、load操作)这样就确保了其他线程读取到的变量的值是最新的(不熟悉这几个操作的同学请先了解java内存模型)。

  注意:volatile可以实现可见性,但是无法实现原子操作。原子操作是与java代码相关的,并不是这么一个关键字既可以控制得了的。(请将可见性和原子操作区分开来,我之前就混淆在一起,分开之后立即通透了)

  java中实现原子操作的方式还是有很多的,但是并不包含volatile,简单的实现方式有:atomic包下的原子操作(通过CAS实现),基本数据类型的读写操作等。

  java中经典的非原子操作如自增实现,普通的i++操作看似只有一句话,但是编译成机器指令之后拥有多少行,不可知,坑顶不是一句就能实现的,这么多命令要执行当然无法保证原子性,这时候我们可以AtomicInteger和AtomicLong原子操作类的getAndIncrement()方法来实现。

  volatile的另一个作用就是避免重排序,使用内存屏障的方式来实现禁止重排序。在单线程环境中当然没有必要禁止重排序,但是在多线程环境中重排序后执行的代码就可能会出错,比如线程A中需要检测线程B中的某一个变量的值,如果没有使用volatile修饰该变量,线程B中针对这个变量的操作就可能会发生重排序,可能会提前执行,这是一旦操作执行,那么线程A就可以会提前得到这个变量的值(或许是在一些线程A的准备工作还未全部准备好的情况,假设这些准备工作在线程B中定义,但是与变量操作无依赖关系,一旦变量操作提前,这些准备工作就会滞后,这是线程A就会在准备工作尚未完成的情况下启动执行后行代码,导致出错)。为变量加上volatile修饰之后,就会禁止其操作的重排序,保证所以的准备工作全部执行完成之后在进行变量操作,然后线程A在准备齐备的情况启动,得以正常执行。

  

java中volatile的简单理解的更多相关文章

  1. java中volatile关键字的理解

    一.基本概念 Java 内存模型中的可见性.原子性和有序性.可见性: 可见性是一种复杂的属性,因为可见性中的错误总是会违背我们的直觉.通常,我们无法确保执行读操作的线程能适时地看到其他线程写入的值,有 ...

  2. java中的二进制运算简单理解

    package test9; public class StreamTest { public static void main(String[] args) { int a = 15;// 0b11 ...

  3. java中线程同步的理解(非常通俗易懂)

    转载至:https://blog.csdn.net/u012179540/article/details/40685207 Java中线程同步的理解 我们可以在计算机上运行各种计算机软件程序.每一个运 ...

  4. Java中Volatile的作用

    Java中Volatile的作用 看了几篇博客,发现没搞懂.可是简单来说,就是在我们的多线程开发中.我们用Volatile关键字来限定某个变量或者属性时,线程在每次使用变量的时候.都会读取变量改动后的 ...

  5. Java中线程同步的理解 - 其实应该叫做Java线程排队

    Java中线程同步的理解 我们可以在计算机上运行各种计算机软件程序.每一个运行的程序可能包括多个独立运行的线程(Thread). 线程(Thread)是一份独立运行的程序,有自己专用的运行栈.线程有可 ...

  6. 【转】java中volatile关键字的含义

    java中volatile关键字的含义   在java线程并发处理中,有一个关键字volatile的使用目前存在很大的混淆,以为使用这个关键字,在进行多线程并发处理的时候就可以万事大吉. Java语言 ...

  7. Java中Volatile关键字详解

    一.基本概念 先补充一下概念:Java并发中的可见性与原子性 可见性: 可见性是一种复杂的属性,因为可见性中的错误总是会违背我们的直觉.通常,我们无法确保执行读操作的线程能适时地看到其他线程写入的值, ...

  8. 转:java中volatile关键字的含义

    转:java中volatile关键字的含义 在java线程并发处理中,有一个关键字volatile的使用目前存在很大的混淆,以为使用这个关键字,在进行多线程并发处理的时候就可以万事大吉. Java语言 ...

  9. 多线程(三) java中线程的简单使用

    java中,启动线程通常是通过Thread或其子类通过调用start()方法启动. 常见使用线程有两种:实现Runnable接口和继承Thread.而继承Thread亦或使用TimerTask其底层依 ...

随机推荐

  1. Angular JS中的路由

      前  言            本章节将为大家介绍 AngularJS 路由.AngularJS 路由允许我们通过不同的 URL 访问不同的内容.通过 AngularJS 可以实现多视图的单页We ...

  2. 如何在maven pom.xml文件中设置Java编译器版本

    今天遇到一个问题: 在Eclipse中用maven创建一个新的web项目,然后再用maven update一下,则JDK版本自动变为1.5. 通过查找资料,终于发现maven编译器插件(Maven C ...

  3. 简单Elixir游戏服设计- 游戏玩法介绍

    抄以前的,做了点修改. 到目前为止,我们完成了玩家的数据和进程建模,现在介绍游戏玩法. 为什么我们还不做客户端接入.协议指定呢?为什么还没有网关和数据存储呢.在我接手的游戏, 这些通常已经定下来了,我 ...

  4. 非对称加密RSA的C#实现

    1.对称加密算法 对称加密是最快速.最简单的一种加密方式,加密(encryption)与解密(decryption)用的是同样的密钥(secret key). 对称加密有很多种算法,由于它效率很高,所 ...

  5. HDU1081 最大字段和 压缩数组

    最大字段和题型,推荐做题顺序: HDU1003    HDU1024     HDU1081  zoj2975  zoj2067 #include<cstdio> #include< ...

  6. WPF: ShowDialog() 切换到其他应用窗口后,再切换回来无法让子窗口总在最上方

    按说ShowDialog()是模态窗口,应该在主窗口的上方,但是打开其他应用窗口再切换回来的时候,发现子窗口不见了,主窗口又不能操作. 另外子窗口设置成不在任务栏显示,只能通过Alt-Tab来切换到子 ...

  7. 博客发在win10.me

    看到了http://www.win10.me/?page_id=58 说可以把自己的文章投给win10.me 我试试 抱着没有的心态 居然可以 我联系九幽,和他们说我写了很多博客,质量不好,他们说好 ...

  8. 利用大白菜制作多系统启动U盘(win+ubuntu+PE+...)

    网上提供的方法很多都过时了,不适用,要不就是讲的不清楚 我结合http://www.xuebuyuan.com/848003.html大神的方案,加以研究,整理出了此篇文章 先看下最终成果: 好了,感 ...

  9. maven的java web项目启动找不到Spring ContextLoaderListener的解决办法

    用maven搭建的java web项目,上传到git仓库后,当同事clone下来项目,部署到tomcat运行时,就报了如下错误,即启动web项目时,加载web.xml文件,找不到spring的监听器, ...

  10. 64、django之模型层(model)--建表、查询、删除基础

    要说一个项目最重要的部分是什么那铁定数据了,也就是数据库,这篇就开始带大家走进django关于模型层model的使用,model主要就是操纵数据库不使用sql语句的情况下完成数据库的增删改查.本篇仅带 ...