volatile是Java提供的一种轻量级的同步机制,在并发编程中,它是担任了重要的角色。同synchronized相比(synchronized通常称为重量级锁),volatile更轻量级。
想要了解votatile的来龙去脉,就必须了解CPU缓存模型和java内存模型,本文介绍前者。
众所周知,计算机所有的运算操作都是在cpu寄存器来完成的,运算操作无非就是数据的读取和写入操作,但CPU能访问的数据只能是计算机内存(RAM),虽然相比于普通硬盘和固态硬盘,RAM的速度远超这两者,但比起CPU的处理速度来说,这之间的差距可达数千倍。
举个简单的例子,随着光纤的普遍接入,网络速度大大提高,可不管下载速度如何提高,它的上限都受制于硬盘的写入速度,就算下载速度超过了10GB/s,可固态硬盘写入速度撑死也只能达到它的十分之一。
CPU也一样,由于运算速度和内存访问速度上面的不对等,导致CPU资源会受到极大的限制,于是就有在CPU主存和内存之间增加了缓存的设计。
看图中I9 9900K的参数,现在的缓存可以增加到3级。
在程序的运行中,会将运算所需要的数据复制一份到CPU缓存中,这样CPU就可以直接对缓存中的数据进行运算,当运算结束后,将缓存中的数据刷新到内存中,依靠这样的方式,极大提高了CPU的吞吐量。
在提高了吞吐量的同时,也出现了另一个问题,缓存不一致、
试想有一段运算操作:i++
这里就存在和java一样的多线程问题,在两个线程同时对i进行操作的时候,每个线程都有自己的工作内存,变量i会在多个线程的本地内存中都保存一个副本,假设i值为1,在同一时间的两个线程读取i的值保存在cpu cache中,经过运算后再写入内存,但i再经过两次自增后,最后写入内存的值还有可能是2。
第一种方式是一种悲观的方式,只有一个cpu能抢到锁进行运算,而其他cpu就进入阻塞状态。这种方式的效率低下,所以就有了第二种方式。
缓存一致性协议的大致思想是:
如果cpu在操作数据的时候,发现数据是一个共享变量(其他cache也保存了副本),就进行如下操作:
如果您发现该资源为电子书等存在侵权的资源或对该资源描述不正确等,可点击“私信”按钮向作者进行反馈;如作者无回复可进行平台仲裁,我们会在第一时间进行处理!
添加我为好友,拉您入交流群!
请使用微信扫一扫!