关于Volatile关键字含义的一些个人理解
2015-05-08 16:22
579 查看
Volatile关键字出现在一些高级语言中,尤其是支持多线程编程的语言,比如C、C++、Java和C#。这些语言赋予了Volatile关键字不同的含义,但是总的来说,引入该关键字的出发点应该都是类似的。
在将volatile关键字之前,我们先了解一下计算机的缓存系统。根据不同的读取速度,计算机的存储器可以分为disk、memory、cache和register几大类。读写速度依次递增,存储容量依次递减。当然cache还能进一步细分成几级,如一级缓存、二级缓存和三级缓存,缓存还包括缓存命中(cache hit)和缓存失效(cache miss)以及缓存的替换策略等,关于缓存,还有更多知识,这里就不一一解释了。接下来,我们考虑如下一个场景:
一份数据被load进memory,当cpu需要处理该数据时,又会被load进cpu中的register。由于cpu的处理速度比memory的读写速度快很多,就会造成cpu的等待,形成性能瓶颈。解决办法之一便是加入读写更快的cache作为memory和cpu之间的缓存。有了cache之后,便有了如下问题:假如应用程序开启了两个线程Thread1和Thread2,Thread1和Thread2同时处理该份数据(data),在load进cpu的寄存器之前,data可能会分别缓存在cache1和cache2中。如下图:
Thread1和Thread2在处理完数据之后,可能将数据先写到cache1和cache2里,然后在之后的某一时刻再更新到memory上。这种数据更新策略叫”写回(write back)”。与之相对应的更新策略叫”写穿透(write through)”。如果该data不加Volatile修饰,编译器就会对其进行优化——仅仅从缓存中读取data,从而造成数据的不一致。加了Volatile以后,编译器就会认为这个变量的值是随时改变的,编译后的程序就会直接从memory中读取数据,保证Thread1和Thread2读取的数据时一致的(个人理解其实这种策略就是”写穿透”)。
注意几点:
1) volatitle修饰的关键字并非是进行原子性操作的
2) C、C++、Java和C#中的Volatile关键字含义并非完全相同,具体的区别参见不同语言的语法定义
最后,以上信息仅仅是个人意见,可能会有疏忽或错误的地方,恳请批评指正!
[1] http://zh.wikipedia.org/wiki/Volatile变量
[2] http://zh.wikipedia.org/wiki/CPU缓存
[3] http://blog.csdn.net/tyger/article/details/5936954(写回和写穿透)
[4] http://www.cnblogs.com/yc_sunniwell/archive/2010/06/24/1764231.html
[5] http://www.cnblogs.com/aigongsi/archive/2012/04/01/2429166.html
在将volatile关键字之前,我们先了解一下计算机的缓存系统。根据不同的读取速度,计算机的存储器可以分为disk、memory、cache和register几大类。读写速度依次递增,存储容量依次递减。当然cache还能进一步细分成几级,如一级缓存、二级缓存和三级缓存,缓存还包括缓存命中(cache hit)和缓存失效(cache miss)以及缓存的替换策略等,关于缓存,还有更多知识,这里就不一一解释了。接下来,我们考虑如下一个场景:
一份数据被load进memory,当cpu需要处理该数据时,又会被load进cpu中的register。由于cpu的处理速度比memory的读写速度快很多,就会造成cpu的等待,形成性能瓶颈。解决办法之一便是加入读写更快的cache作为memory和cpu之间的缓存。有了cache之后,便有了如下问题:假如应用程序开启了两个线程Thread1和Thread2,Thread1和Thread2同时处理该份数据(data),在load进cpu的寄存器之前,data可能会分别缓存在cache1和cache2中。如下图:
Thread1和Thread2在处理完数据之后,可能将数据先写到cache1和cache2里,然后在之后的某一时刻再更新到memory上。这种数据更新策略叫”写回(write back)”。与之相对应的更新策略叫”写穿透(write through)”。如果该data不加Volatile修饰,编译器就会对其进行优化——仅仅从缓存中读取data,从而造成数据的不一致。加了Volatile以后,编译器就会认为这个变量的值是随时改变的,编译后的程序就会直接从memory中读取数据,保证Thread1和Thread2读取的数据时一致的(个人理解其实这种策略就是”写穿透”)。
注意几点:
1) volatitle修饰的关键字并非是进行原子性操作的
2) C、C++、Java和C#中的Volatile关键字含义并非完全相同,具体的区别参见不同语言的语法定义
最后,以上信息仅仅是个人意见,可能会有疏忽或错误的地方,恳请批评指正!
参考资料:
[1] http://zh.wikipedia.org/wiki/Volatile变量[2] http://zh.wikipedia.org/wiki/CPU缓存
[3] http://blog.csdn.net/tyger/article/details/5936954(写回和写穿透)
[4] http://www.cnblogs.com/yc_sunniwell/archive/2010/06/24/1764231.html
[5] http://www.cnblogs.com/aigongsi/archive/2012/04/01/2429166.html
相关文章推荐
- 个人关于“this”关键字的理解
- 关于高考英语阅读理解的一些个人技巧1.17
- 对于C/C++,java的volatile关键字的个人理解
- 关于技术美术的一些个人理解
- 关于java synchronized关键字的一些理解
- 关于KMP的一些个人理解
- 关于内核中spinlock的一些个人理解 【转】
- 关于java多线程关键字volatile的理解
- 【原创】关于操作符重载的一些个人理解
- 关于Java中的关键字volatile的理解
- 关于Python2/3多进程的一些个人理解
- 关于yield关键字的一些理解
- js中关于可视区、实际区域一些知识的个人理解
- 关于C#中 out/ref的一些个人理解
- 关于c#中”ref”和”out”关键字的一些理解
- 关于开发的一些流程和个人理解
- 关于线程方法的一些个人理解
- 关于Bean\Entity\Model\POJO的一些个人理解
- 关于socket的一些个人理解
- 关于.NE弱引用的一些个人理解