采纳答案成功!
向帮助你的同学说点啥吧!感谢那些助人为乐的人
还是不理解使用volatile有什么好处?就算现在没有volatile修饰,等线程1执行完成后将值写入主内存,线程2再判断为true然后执行,除了慢一点点也没什么影响啊
你好,有了volatile,一旦别的线程修改,这里可以得到最新的值,也能避免某些重排序。
线程1把写入主内存后,线程2如果之前已经执行了while(!inited) 判断时,那么你是无法确定线程2什么时候可以读到最新的主内存里的值的,而不是简单的慢一点点的。这里的写法也是期望在inited变成true时立刻开始执行后面的程序。
这是第一个原因,再说第二个原因,也是一个更重要的原因。如果不加volatile,线程1的两段代码可能发生重排序,就是先执行inited=true, 再执行context=loadContext(), 这样一来就会出现inited=true时,context还有短暂为空的一段时间。这时如果线程2执行时发现inited为true了,去执行doSomethingWithConfig(context)时,就会出现操作的是一个空值了,这个明显不符合预期。而线程2之前的循环判断就是为了保证loadContext()肯定执行。这时有了volatile就不一样了,他可以保证线程1先执行context=loadContext(),再执行inited=true,之后线程2才可能执行到doSomethingWithConfig(context)。保证代码执行符合预期。
我们在处理涉及到多线程共享的变量时,很多情况下需要读到变量准确的值和避免重排序,尽可能的保证当前线程的执行符合预期。这个例子还算简单,复杂一点的,有时你使用了过期的变量的值,而你以为你拿到的最新的值,就可能会导致代码的执行远离你的预期,导致程序执行出错,也可能带来很大的损失。
而为了避免这个问题,jvm里定义了volatile关键字,在需要的时候使用它,利用它的可见性及避免重排序,来尽可能保证代码按照你的预期执行。
精彩!!
老师,您好,这里有个地方不明白,请问为什么会发生重排序啊……也就是线程一为什么先执行第二句,再执行第一句
两行代码如果没什么关联的话,对应cpu的指令也会没什么关联,对于计算机而言,先执行哪个都可以(对于我们而言也是这样),因此在执行时可能会做一些优化,就是重排序。可是很不幸的是,一旦重排序,多线程下就会有问题,就是课程里说的这种case,因此需要引入锁、volatile等限制某些重排序。
登录后可查看更多问答,登录/注册
构建完整并发与高并发知识体系,倍增高薪面试成功率!
1.7k 1
1.1k 18
1.2k 15
3.6k 12
1.2k 12