volatile的理解和使用
package thread; /**
* Created by Administrator on 2017/1/15.
*/
public class Counter {
public volatile static int count = 0; public static void inc() { try {
Thread.sleep(1);
} catch (InterruptedException e) {
} count++;
System.out.println(count);
} public static void main(String[] args) { //同时启动1000个线程,去进行i++计算,看看实际结果 for (int i = 0; i < 1000; i++) {
new Thread(new Runnable() {
public void run() {
Counter.inc();
}
}).start();
} //这里每次运行的值都有可能不同,可能为1000
System.out.println("运行结果:Counter.count=" + Counter.count);
} }
volatile工作中没用到过,买了本《java并发编程的艺术》,准备系统的学习下多线程.
volatile是轻量级的synchronized,它能够在多处理器开发中保证了共享变量的“可见性”.
可见性:当一个线程修改了一个共享变量时,另一个线程能够读到这个被修改该后的值.
当一个被volatile修饰的共享变量的值发生改变,
1.该值会从处理器缓存中写会到系统内存中.
2.这个写回内存的操作会使得其他cpu里缓存了该内存地址的数据失效(为了提高处理速度,处理器不直接很内存进行通信,而是先将系统内存的数据读到内部缓存后再进行操作.).
这个代码比较有趣:
1.可将volatile删掉,然后发现,输出的结果,并没有1000,因为多个线程在同时对一个变量进行读写,造成有些读写没有保存下来.
2.可以看到
System.out.println("运行结果:Counter.count=" + Counter.count);
这句代码最后输出的数不是1000,因为main函数直到执行结束,仍然还有线程在运行,main函数输出的count并不是最后的结果值.
3.可以看到,当使用volatile后,虽然main函数输出的值仍然不是1000,但在打印出来的数据中可以搜到1000,说明共享变量确实是得到了想要的值,尽管不是最后一个打印出来的(这和代码中thread.sleep(1)有关系,还可能和线程切换,处理器时间片有关,我并不是很清楚),可以将thread.sleep代码去掉,可以得到按顺序输出的数值,最后输出的是1000.
(多线程第一篇)
volatile的理解和使用的更多相关文章
- Java线程工作内存与主内存变量交换过程及volatile关键字理解
Java线程工作内存与主内存变量交换过程及volatile关键字理解 1. Java内存模型规定在多线程情况下,线程操作主内存变量,需要通过线程独有的工作内存拷贝主内存变量副本来进行.此处的所谓内存模 ...
- volatile变量理解 via《Java并发编程实战》
第3章:对象的共享 volatile关键字的理解 volatile变量,用来确保将变量的更行操作通知到其他线程.当变量申明为volatile类型后,编译器与运行时都会注意带这个变量时共享的,因此不会将 ...
- 对volatile的理解--从JMM以及单例模式剖析
请谈谈你对volatile的理解 1.volitale是Java虚拟机提供的一种轻量级的同步机制 三大特性1.1保证可见性 1.2不保证原子性 1.3禁止指令重排 首先保证可见性 1.1 可见性 概念 ...
- volatile的理解
用法解释 一旦一个共享变量(类的成员变量.类的静态成员变量)被volatile修饰之后,那么就具备了两层语义: 1)保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对其 ...
- 对于volatile的理解
哎.要学的东西太多,时间太少.一周的工作下来要总结的东西太多,还处理不完,越积越多.大周末的好想出去玩啊.... 得嘞,废话止于此. 无聊时候乱看网页发现了volatile的一篇文章,以前曾经对vol ...
- 关于java多线程关键字volatile的理解
volatile关键字的作用是强制从公共堆栈中取得变量的值,而不是从线程私有数据栈中取得变量的值. 使用volition关键字增加了实例变量在多个线程间的可见性.但volition有个致命的缺点就是不 ...
- (转)volatile 的理解
对于(volatile unsigned char *)0x20我们再分析一下,它是由两部分组成: 1) (unsigned char *)0x20,0x20只是个值,前面加(unsigned cha ...
- Volatile关键字理解
Volatile定义 为了确保共享变量能被准确和一致的更新,线程应该确保通过排他锁单独获得这个变量.Java语言提供了volatile,在某些情况下比锁更加方便.如果一个字段被声明成volatile, ...
- java中关于volatile的理解疑问?
作者:xyzZ链接:https://www.zhihu.com/question/49656589/answer/117826278来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请 ...
随机推荐
- PHP获取POST方式的XML数据
今天做微信支付开发,微信服务器回调的时候,会发送XML数据到我的服务器,用以往的POST,GET是获取不到的 百度了一下,应该是 $file_in = file_get_contents(" ...
- 转 Android 编程下两种方式注册广播的区别
常驻型广播 常驻型广播,当你的应用程序关闭了,如果有广播信息来,你写的广播接收器同样的能接收到,它的注册方式就是在你应用程序的AndroidManifast.xml 中进行注册,这种注册方式通常又被称 ...
- javascript中的正则匹配函数exec(),test(),match()
test() var str = "cat";var reStr = /cat/;alert(reStr.test(str)); 输出为:true 它的返回值为true or fa ...
- Tomcat Neither the JAVA_HOME nor the JRE_HOME environment variable is defined
一眼就能看出来是jdk的环境有问题,但是用了这么久的jdk一直都配置的好好的,怎么一到Tomcat上就这么矫情了. 最后查解决方案,原来是我的jdk从官网直接下载的,虽然我修改了java_home,但 ...
- cc2530启动流程---广播发送数据
//操作系统任务初始化 void osalInitTasks( void ) { uint8 taskID = ; // 分配内存,返回指向缓冲区的指针 tasksEvents = (uint16 * ...
- 基于Nginx的Rtmp流媒体服务器环境搭建
一.编译安装 wget http://nginx.org/download/nginx-1.4.2.tar.gz wget https://github.com/arut/nginx-rtmp-mod ...
- 在Delphi中使用C++对象(转)
源:http://blog.csdn.net/henreash/article/details/7352335 Delphi是市场上最好的RAD工具,但是现在C++占据着主导地位,有时针对一个问题很难 ...
- 将Web项目访问的URL项目名设置为"/"
工具:Eclipse 步骤: 1.鼠标右键项目名--->properties--->Web Project Setting--->Context root. 将Context roo ...
- MariaDB GTID 复制同步
MariaDB GTID 复制同步 GTID:Global Transaction ID,全局事务ID,在整个主从复制架构中任何两个事物ID是不能相同的.全局事务ID是Mster服务器生成一个128位 ...
- kafka 集群部署 多机多broker模式
kafka 集群部署 多机多broker模式 环境IP : 172.16.1.35 zookeeper kafka 172.16.1.36 zookeeper kafka 172.16 ...