volatile

volatile关键字的主要作用是使变量在多个线程间可见

使用方法:

private volatile int number=0;

图示:

两个线程t1和t2共享一份数据,int a=0,但是两个线程间是不可见的,t1修改a=10,但对于t2来说a还是从0变到20,两个线程是独立的,不可见的;

我想做的是a如果变化了,t1和t2实时的知道a变化了,即a不是从0变到20,而是从10变到20;即t1对a发生修改,t2实时知道a发生变化了;同理,t2中a变成20了,t1也能马上知道值变成20了;volatile关键字就能实现这个.

运行结果如下:

虽然输出了isRunning的值已经被设置成了false,但是线程仍然在运行;这是什么原因呢?

这是java  jdk的原因

java  jdk在执行一个程序时,都会分配一个单独的空间,但是在jdk1.5以后,它对每一个线程做了一个优化,对每个线程加了一块独立的运行空间,这块空间装主内存的一些引用(当前线程的一些引用变量),相当于拷贝了一份副本,线程运行时直接去副本取内容.这样做的目的是,让线程在执行时效率更高

加volatile关键字后:

这是为什么呢?

内存分析图:

volatile只具有可见性不具备原子性(原子操作是不可分割的,在执行完毕不会被任何其它任务或事件中断)

总结:

volatile关键字虽然拥有多个线程之间的可见性,但是不具备同步性(也就是原子性),可以算上是一个轻量级的synchronized,性能要比synchronized强很多,不会造成阻塞(在很多开源的架构里,比如netty的底层就大量使用volatile,可见netty一定是非常不错的)

这里需要注意:一般volatile用于只针对于多个线程可见的变量操作,并不能代替synchronized的同步功能.

测试不具备原子性,例如:

一个count,10个数组,每组加1000次,所以count结果应该为1000*10=10000

打印结果:

说明volatile修饰不具备原子性.为啥呢??

第一个线程执行完1000,完了之后要打印,但是打印出来需要时间,在打印过程中,有可能第二个线程进去执行count++,所以打印出来的结果就如上图所示,但是观察最后一个线程,如果满足原子特性的化就一定是10000

如何保证原子性操作呢?

使用AtomicInteger这个类,去多线程并发的原子操作,它有很多类型

======================================================================

示例总结:

volatile关键字只具有可见性,没有原子性.要实现原子性建议使用atomic类的系列对象

06.volatile关键字的更多相关文章

  1. C/C++中volatile关键字详解

    1. 为什么用volatile? C/C++ 中的 volatile 关键字和 const 对应,用来修饰变量,通常用于建立语言级别的 memory barrier.这是 BS 在 "The ...

  2. C:详解C中volatile关键字

    原文地址:http://www.cnblogs.com/yc_sunniwell/archive/2010/06/24/1764231.html volatile提醒编译器它后面所定义的变量随时都有可 ...

  3. 【转】 详解C中volatile关键字

    转自: http://www.cnblogs.com/yc_sunniwell/archive/2010/06/24/1764231.html volatile提醒编译器它后面所定义的变量随时都有可能 ...

  4. 详解C中的volatile关键字【转】

    本文转载自:http://www.cnblogs.com/yc_sunniwell/archive/2010/06/24/1764231.html volatile提醒编译器它后面所定义的变量随时都有 ...

  5. TQ2440之定时器中断0——volatile关键字的重要作用

    近日,在学习<ARM处理器裸机开发实战--机制而非策略>一书,在TQ2440开发板上,按照书中实例以及光盘配套程序源代码进行Timer0中断试验,编译成功后烧写到开发板上,没有任何反应,反 ...

  6. 【转】volatile关键字。编译器不优化,多线程会改。防止随时变动的

    来自:http://www.cnblogs.com/yc_sunniwell/archive/2010/07/14/1777432.html 1. 为什么用volatile? C/C++ 中的 vol ...

  7. C中的volatile关键字

    volatile提醒编译器它后面所定义的变量随时都有可能改变,因此编译后的程序每次需要存储或读取这个变量的时候,都会直接从变量地址中读取数据.如果没有volatile关键字,则编译器可能优化读取和存储 ...

  8. Java并发之(1):volatile关键字(TIJ21-21.3.3 21.3.4)

    Java并发Java服务器端编程的一项必备技能. ** 1 简介    volatile是java中的一个保留关键字,它在英语中的含义是易变的,不稳定的.volatile像final.static等其 ...

  9. 详解C中volatile关键字(转)

    volatile提醒编译器它后面所定义的变量随时都有可能改变,因此编译后的程序每次需要存储或读取这个变量的时候,都会直接从变量地址中读取数据.如果没有volatile关键字,则编译器可能优化读取和存储 ...

随机推荐

  1. AVR单片机教程——按键状态

    好久没更新了,今天开始继续,争取日更. 今天我们来讲按键.开发板的右下角有4个按键,按下会有明显的“咔嗒”声.如何检测按键是否被按下呢?首先要把按键或直接或间接地连接到单片机上.与之前使用的4个LED ...

  2. HTML常用技巧

    1. 为网页链接添加快捷键:accesskey 属性 https://zhidao.baidu.com/question/2267343500557447508.html 2. 键盘事件设置快捷键:h ...

  3. hdu1016 Prime Ring Problem【素数环问题(经典dfs)】

    Prime Ring Problem Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Other ...

  4. Scala 函数入门之过程、lazy值和异常

    Scala 过程  在Scala中,定义函数时,如果函数体直接包裹在了花括号里面,而没有使用=连接,则函数的返回值类型就是Unit.这样的函数就被称之为过程.过程通常用于不需要返回值的函数. 过程还有 ...

  5. mysql_重置密码

    # 修改编码 ```pythonshow variables like '%char%'; #查看当前使用的编码 1.打开配置文件: vim /etc/mysql/my.cnf 2.在[client] ...

  6. jmeter_分布式测试

    背景:         由于Jmeter本身的瓶颈,当需要模拟数以千计的并发用户时,使用单台机器模拟所有的并发用户就有些力不从心,甚至还会引起JAVA内存溢出的错误.要解决这个问题,可以使用分布式实测 ...

  7. yum安装k8s集群

    k8s的安装有多种方式,如yum安装,kubeadm安装,二进制安装等.本文是入门系列,只是为了快速了解k8s的原理和工作过程,对k8s有一个快速的了解,这里直接采用yum安装 的1.5.2为案例进行 ...

  8. bean标签解析与注册

    protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) { BeanDefin ...

  9. Python之TensorFlow的变量收集、自定义命令参数、矩阵运算、梯度下降-4

    一.TensorFlow为什么要存在变量收集的过程,主要目的就是把训练过程中的数据,比如loss.权重.偏置等数据通过图形展示的方式呈现在开发者的眼前. 自定义参数:自定义参数,主要是通过Python ...

  10. Java任务调度框架Quartz教程

    一.什么是quartz作业调度? Quartz框架是一个全功能.开源的任务调度服务,可以集成几乎任何的java应用程序—从小的单片机系统到大型的电子商务系统.Quartz可以执行上千上万的任务调度. ...