java volatile询问

如果两个线程同时写volatile变量会出现什么问题?一个面试官问我的,求大神解答
#Java工程师#
全部评论
volatile能保证原子性,保证的是对64位long double简单赋值操作和读操作的原子性。但是复杂操作例如自增不能保证。但是你不能说没有保证自增volatile就不具有原子性,因为自增也是由3个原子性操作相加的符合操作。类比的你可以去看collections类同步synchronizedMap过后的map,他的put get remove一样是原子性的,但是如果你调用两个原子性操作就会出错。比如containsKey之后进行remove,并发时会出错的。
点赞 回复 分享
发布于 2017-04-23 19:02
内存屏障
点赞 回复 分享
发布于 2017-04-23 16:25
volatile不能保证线程安全
点赞 回复 分享
发布于 2017-04-23 16:27
不可能同时写,当某个线程a往主存写的时候,会锁住cpu缓存行,导致另一个线程b的相同变量无法同时写入与读取,当a写完时,由happen-before规则,b线程会重新读取主存最新的值,也就是说,volatile是轻量级的synchronized,不会导致线程切换。
点赞 回复 分享
发布于 2017-04-23 16:38
volitile能保证读和写的原子性
点赞 回复 分享
发布于 2017-04-23 17:14
volatile 不能保证原子性!!!绝对不能。认为能的是对java理解很大的常见误区。 volatile 保证的是内存可见性。也可用来防止指令重排序(就是上面有人提到的内存屏障,也是happens-before的一条原则)
点赞 回复 分享
发布于 2017-04-23 18:23
可能读到被修改之前的值。因为读到缓存的数据了。
点赞 回复 分享
发布于 2017-04-23 18:37
楼主可以看看一位大神海子的一篇博客 volitale讲的很详细
点赞 回复 分享
发布于 2017-04-23 20:46
个人看法:如果写操作是i++这类的操作是会出现并发问题的,因为自增操作会分解成三个操作完成,这个大家都知道;如果写操作是i = 1这类赋值操作就不会有问题,因为赋值操作在jvm层面也是原子操作,加上volatie实现的可见性,就可以保证多个线程对这个变量的修改一定会有个先后顺序,最后这个变量的值就是最后执行的线程修改的值。
点赞 回复 分享
发布于 2017-04-23 21:50
对于基本变量的赋值和读取能保证原子性,其他不行。既然问的是使用了volatile,那我们的前提就是使用正确的情况下,根据happen-before原则,是不会有问题的,不可能是同时
点赞 回复 分享
发布于 2017-04-23 23:28
至少在cpp里,不能保证线程安全…只是禁止了编译器的优化工作…
点赞 回复 分享
发布于 2017-04-23 23:55
内存可见性和禁止指令重排序
点赞 回复 分享
发布于 2017-04-24 07:38

相关推荐

粗心的雪碧不放弃:纯学历问题,我这几个月也是一直优化自己的简历,后来发现优化到我自己都觉得牛逼的时候,发现面试数量也没有提升,真就纯学历问题
点赞 评论 收藏
分享
一名愚蠢的人类:多少games小鬼留下了羡慕的泪水
投递荣耀等公司10个岗位
点赞 评论 收藏
分享
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务