什么时候需要加volatile关键字?它能保证线程安全吗?

这是一道常规面试题,对于各位大牛来说不算什么。但是怎样才能给小白讲明白呢?我尽力吧。

先来看看这个关键字吧。volatile,查词典知道它的意思是“adj. 易变的,动荡不定的,反复无常的;(计算机内存)易失的”。说到它就要谈到CPU的高速缓存。我们知道一个程序运行起来,里边的变量都是在内存的,CPU为了提高效率,会把变量读到它自己的缓存中,这个缓存的读写速度比内存快很多。只有在缓存不够用的时候,才会根据算法把变量写回到内存。如果是单个CPU这样不会造成什么困扰,因为单个CPU不会存在缓存和内存不一致的情况:读的时候都读取缓存,缓存没有就读内存。但是时代进步了,现在计算机都是多核了。多个CPU的情况下,这个就有问题。例如定义一个变量 int age = 18; CPU_0读到自己缓存然后做个运算age++, 就变成19了,然后写到缓存。这个时候内存中的值依然是18,因为并没有触发“写回”。如果CPU_1去读取age,读到的值依然是18而不是19, 因为CPU_0对age所做的修改“不可见”。设想一下如果两个核都将age写回到内存回怎样?只有后写的那个会生效。

volatile这个关键字,解决的是变量修改的“可见性”问题。被volatile修饰的变量,不会被CPU放到它的缓存中,而是在内存中,这样任何一个CPU修改了它的值,其他的CPU马上就能够读到。

上面就是volatile这个关键字的作用。那么什么时候需要加volatile呢?如果一个变量需要被多个线程共享,就需要添加volatile。第二个问题:它能保证线程安全吗?我的答案是:它跟线程安全没有什么关系。打个比方,你有100个硬币放大街上,你和其他路人都能够看到,都可以拿。你指望最后100块钱都到你口袋吗?保证线程安全的一个办法是加锁:你把钱锁进箱子里,之后拿到唯一钥匙的人才能够拿钱。

如果不加锁,那只能期望有人不拿钱,而是放钱进去了。例如2022元,跟年号对齐。

初浅理解,欢迎大神探讨指导。

你可能感兴趣的:(JAVA,缓存,java,多线程,后端)