java多线程中的static和voilate

最近研究voilate原理的时候发现一个问题,voilate关键字是保证多个线程私有内存变量与主内存变量保持一致,来实现线程的可见性,突然有个问题,将变量申明为static,使多个实例共享这个变量不也可以实现多线程共享变量吗?那voliate存在的意义是啥?还不能保证原子性。有没有人帮忙分析下static和voilate

3个回答

看来你还不太理解可见性的含义,多线程环境下,如果某个变量可以被多线程共享,那么每个线程都可以读取并且修改这个变量,
这样有什么问题呢,比如有变量X(普通变量),线程A B
普通变量无法保证:A线程修改了变量后B线程访问到的是A修改后的值,B从主内存中拿到的并不是X最新的值,这叫内存不可见
如果X用voilate修饰会有什么不一样呢?在任何一个线程修改了X的值后,如果有其他线程想要读取X,jvm会强制更新主内存中X的值为最新的值然后再复制到
线程的本地内存中,这就保证了多线程环境下对于X变量的每次读取都可以读到最新值,这叫内存可见

weixin_39197944
weixin_39197944 回复wb_snail: 线程可见的概念并不是仅仅是共享,而是数据的同步
2 年多之前 回复
weixin_39197944
weixin_39197944 回复wb_snail: 这里迷糊的原因是把线程当成普通对象来对待了!!! 虽然他是对象,但是使用的是自己内存空间数据的对象!
2 年多之前 回复
weixin_39197944
weixin_39197944 回复wb_snail: 恩恩 我知道了,static区别于普通变量在多线程里面仅仅是提供了可见,但是不能保证数据的更新(相对于普通变量只是提供了共享,但其实是不可见),而voilate是可以保证一个变量在线程间通信并且实时更新,我之前一直以为static可以同步更新数据,突然明白了,线程运行使用的是单独的内存区,static是提供了共享,但没有更新线程内存中的数据。。。是我自己的问题! 谢谢,明白了
2 年多之前 回复
wb_snail
wb_snail 回复weixin_39197944: 不不不,volatile的作用不是共享啊我晕,多线程读取修改一个静态变量,这是保证不了每次线程读取到的变量值都是最新值的啊
2 年多之前 回复
weixin_39197944
weixin_39197944 回复wb_snail: 我说一个武断的想法,需要共享的变量你用voilate来实现功能,我都可以用static来做也可以?在那种业务场景下voilate才能体现他的价值?
2 年多之前 回复
weixin_39197944
weixin_39197944 回复wb_snail: 恩恩,我明白你说的可见性是针对线程之间而言的,static是针对作用域而言,是两个角度,但是既然static可以保证可见性和原子性,那为什么还要整出个voilate,而且voilate修饰的变量还不能保证原子性,如i++,还需要加同步锁,用static把线程当做对象来处理就直接可以实现变量的同步修改,这样voilate感觉特别鸡肋和多余,没有存在的必要
2 年多之前 回复
wb_snail
wb_snail 回复wb_snail: 也就是说不管你是static也好,普通实例变量也好,他们都可以被多线程访问到这一点上是没有区别的(可能你误解的点在这里,private static变量可以被这个类的所有实例访问到,这里可以涉及到多线程没错,实例变量只可以被他的所属对象访问到,这里也会涉及到多线程,因为多个线程可以只用这一个对象,那么在多线程的可见性问题上他们二者是不是没有区别?),只要变量可以被多线程访问到就会存在可见性问题,而volatile修饰的变量就可以解决这个问题。
2 年多之前 回复
wb_snail
wb_snail 回复weixin_39197944: 两个概念,static变量与实例变量的区别你说的没错,但是在不可见性上这两者是一样的。static是可以共享没错,但是正因为他可以被共享所以才会存在多线程之间不可见性啊。这与他是不是类变量没有关系哦。其实你说的共享可以算作是作用域的概念,这里的可见性是主存中变量的值与线程本地内存中的值不一致问题,不一样哦
2 年多之前 回复
weixin_39197944
weixin_39197944 回复weixin_39197944: 用static保证可见性相当于不管有多少个线程我就一个,都来改这一个,voliate是有几个线程就复制几份,改了同步更新到每一份。两种方式都可以实现变量在多线程中共享啊
2 年多之前 回复
weixin_39197944
weixin_39197944 你说的普通变量只是实例变量,并不是类变量,普通变量在多线程中肯定是不可见的,但是静态变量呢?线程本质上也是一个对象,静态变量对所有对象(线程)共享有什么问题?
2 年多之前 回复

@wb_snail 感觉就是从两个角度来看这个问题,感觉不用深究下去了。。。一个是从作用域与对象的角度,一个是从线程之间的通信角度(可见性)。

volatile的底层是让所有的缓存失效,总线通知其他的缓存更新最新的数据。

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问