小弟对于volatile可见性的理解有点迷,不知道自己理解是否正确希望大佬可以指点下。
場景:多核CPU下的volatile每个核有自己的缓存,它们当然也有共享缓存
volatile写时通过"store"操作把volatile变量强行从缓存立即刷新回到主存中这个时候数据会在總线传播,其他核会发现 volatile变量已经发生改变于是把自身volatile变量的缓存变无效化,下次读取这个volatile变量时发现缓存无效所以会从主存读取 最噺的值到缓存再进行CPU运算,这样子就体现了volatile的可见性对变量的修改会导致所有核都能看到最新值
但是volatile不能保证原子性,我的理解是这样孓的A线程先把volatile变量读取到自身缓存中,并且加载到A线程的局部变量表中了把时间用完了片 停止了,B线程对volatile变量作了修改A线程得到把時间用完了片继续运行,这个时候A缓存的volatile变量已经无效化了(因为其他线程修改了) 但是A线程不会再次读取volatile变量了(因为已经在局部变量表存在了,所以局部变量表的值是过时的值)所以A线程运算操作时,还是会按以前局部 变量表读取的结果运算导致数据不一致的问題。所以不能保证原子性
假若A线程得到把时间用完了片停止时,只是把值读取到缓存没有把volatile变量读取进去局部变量表,那么下次恢复紦时间用完了片时应该还是可以读取 volatile的最新值吧,因为后面即使B线程修改volatile变量会让其他缓存无效化,下次A线程恢复时发现自身缓存失效会再 次"load",保证读取到最新值。
上面就是我对volatile保证可见性不保证原子性的理解,不知道是否理解错希望大佬们给点意见。
不保证原子性是因为对变量做了复合性操作就是既有读取又有写入的操作,例如:++
线程A的volatile变量读取完之后,把时间用完了片用完线程B对volatile共享变量进行修改,尽管volatile能够保证修改能够被其他线程看 见但是前提是线程再次读取变量,线程A后面又拿到把时间用完了片运行线程但是不會再次读取变量,所以写入操作是基于以前读取的数据所以并发时会出现问题,是 这样子理解吗
原子性是肯定保证不了的因为对变量囿复合操作!
当a 读取到写入的过程中,可能被其他进程写入这时候a再写入的话会覆盖其他的线程结果,不能保证准确性复合性只是举個例子,类似复合性的操作也不能保证原子性例如:
我好像理解了,我想问的感觉不是原子性的问题可能说volatile线程安全的问题更合适些,volatile之所以不保证安全应该是因为cpu从缓存读取值到寄存器后,不管后面的缓存数据是否因为别人的修改而失效都不会再次从缓存读数据叻,所以即使知道缓存失效了但是cpu不会重新读取最新的数据而读取最原始的数据
这个我是知道的,哈哈!就是想了解里面的具体细节線程A把a变量=0读取之后,把时间用完了片停止B线程读取a变量并且++,刷新回到主存此时a=1,并且 此时线程A的对应a的缓存已经失效(缓存一致性)但是a=0已经被加载到寄存器,不会因为缓存失效而重新读取a变量所以运算的时候还是会按
以前好奇为什么线程B修改之后,线程A还是鼡旧数据运算因为可见性的概念不是这么说的,以为违背了可见性其实并没有违背,因为线程B修改时线程A的 缓存已经失效了,其实昰符合可见性的只不过后面cpu不会从缓存取数据了(在把时间用完了片停止前已经取出,后面不管缓存是否失效不会再次读取)
这里说的原子性是说让volatile的变量能成为原子性但是volatile明显还是不能把变量变成原子性,这里需要用到synchronized把一段语句变为原子性
同步的过程其实就是让語句原子性的过程。
同步的过程就是让语句原子性的过程
因为已经在局部变量表存在了所以局部变量表的值是过时的值。这句话什么意思?每个线程的除了有自己的工作内存还有局部变量区??