在Java中将变量标记为volatile
可确保每个线程都能看到最后写入的值,而不是一些陈旧的值。我想知道这是如何实现的。 JVM是否会发出特殊指令来刷新CPU兑换次数?volatile如何实际工作?
回答
从我所了解的情况来看,总是看起来好像缓存在写入后已经被刷新,并且总是看起来好像在读取时直接从内存读取。其效果是一个线程总是会看到来自另一个线程的写入结果,并且(根据Java内存模型)永远不会有缓存的值。然而,实际的实现和CPU指令会因架构而异。
如果您在多个线程中增加变量,或者检查其值并采取一些操作,则不能保证正确性,因为显然没有实际的同步。如果只有线程写入变量而其他人全部读取,则通常只能保证正确执行。
另请注意,64位非易失性变量可以作为两个32位变量读取/写入,因此32位变量在写入时是原子性的,但是64位变量不是。一半可以写在另一半之前 - 所以读取的值可以是旧的或新的值。
这是从我的书签相当有用的页面:
@jgubby:您的最后一段看起来不正确:您无法读取64位易失性数据,其中一位写32位,另一位写32位。 – SyntaxT3rr0r 2010-04-22 22:28:05
@WizardOfOdds:同意。意思是在那里说非易失性变量。 – gubby 2010-04-23 14:49:22
@jbuggy:啊啊,这就是我的想法,但我不敢编辑你的帖子,因为我不知道你的意思:)很高兴帮助,因为否则它有点混乱:)) – SyntaxT3rr0r 2010-04-23 14:56:25
确切地说,会发生什么是处理器特定的。通常有一些形式的记忆障碍指示。刷新整个缓存显然会非常昂贵 - 硬件中存在缓存一致性协议。
同样重要的是,某些优化不是通过字段访问进行的。编译器在考虑多线程时很重要,不要只考虑硬件。
在正确编写的Java程序中发生的事情并不是特定于处理器的。 – gubby 2011-11-01 16:16:29
@jgubby问题确实询问是否发出了特殊说明。 – 2011-11-02 14:17:09
- 1. arguments.callee如何实际工作?
- 2. CompilationRelaxations.NoStringInterning如何实际工作?
- 3. FBConnect如何实际工作?
- 4. JPA如何实际工作?
- 5. ReadAsMultipartAsync如何实际工作?
- 6. UpdatePanel如何实际工作?
- 7. IPython如何?操作员实际工作?
- 8. runloop实际上是如何工作的
- 9. rake db :: migrate如何实际工作
- 10. gZip和DEFLATE如何实际工作?
- 11. 如何获得RegistrationBuilder实际工作?
- 12. JPanel实际上如何工作?
- 13. Math.tan(x)如何实际工作? (Javascript)
- 14. .NET ExecutionContext如何实际工作?
- 15. applicationName属性如何实际工作?
- 16. CSS选择器如何实际工作?
- 17. git clone如何实际工作
- 18. WebResources.axd或ScriptResources.axd如何实际工作?
- 19. 如何绘制(_ rect:CGRect)实际工作?
- 20. 特质特化如何实际工作?
- 21. Eventbug实际上是如何工作的
- 22. JUnit TestCase功能如何实际工作?
- 23. 是ajax实际工作?
- 24. libcurl库的实际工作
- 25. MVC3实体框架4.1RC @ Html.DropDownListFor实际上是如何工作的?
- 26. 实际上,如果声明工作如何
- 27. 运作volatile变量VS实例变量
- 28. MyApp的停在实际设备工作
- 29. localToGlobal不工作 - 对于实际
- 30. JSSOR - lazyloading实际上工作吗?
相关问题(在列表中的第一个实际..)http://stackoverflow.com/questions/1787450/how-do-我了解读存储器障碍和易失 – BalusC 2010-04-22 21:02:34
而且我开始关于无序执行的大量“upvotes”和“favorites”volatile的线程:http://stackoverflow.com/questions/2441279/java-volatile-guaranteed-and-of-order-execution – SyntaxT3rr0r 2010-04-22 22:25:07