多年来,我一直试图理解part处理内存模型和并发性的 Java 规范。我不得不承认我失败得很惨。是的,我了解锁、“同步”、wait() 和 notification()。我可以很好地使用它们,谢谢。我什至对“不稳定”的作用有一个模糊的概念。但所有这些都不是源自语言规范,而是源自一般经验。
这是我要问的两个示例问题。我对特定答案不太感兴趣,因为我需要了解如何从规范中得出答案(或者可能是我如何得出规范没有答案的结论)。
- “挥发性”到底有什么作用?
- 写入变量是原子的吗?它取决于变量的类型吗?
我不会尝试在这里实际回答您的问题 - 相反,我会将您重定向到我看到推荐的关于该主题的建议的书:Java 并发实践.
警告一句:如果有are答案在这里,预计其中不少是错误的。我不打算发布详细信息的原因之一是因为我很确定I'd至少在某些方面是错误的。当我说每个认为自己可以回答这个问题的人实际上有足够严格的能力来正确回答的机会几乎为零时,我的意思并不是对社区的任何不尊重。 (Joe Duffy 最近发现了一些令人惊讶的 .NET 内存模型。如果他能弄错,那么像我们这样的凡人也能弄错。)
我仅就一个方面提供一些见解,因为它经常被误解:
波动性和原子性之间存在差异。人们通常认为原子写入是易失性的(即,如果写入是原子的,则无需担心内存模型)。这不是真的。
波动性是指执行读取的一个线程(逻辑上,在源代码中)是否会“看到”另一个线程所做的更改。
原子性是指如果发生变化是否有可能is看到,只有部分变化会被看到。
例如,以写入整数字段为例。这保证是原子的,但不是易失性的。这意味着如果我们有(从 foo.x = 0 开始):
Thread 1: foo.x = 257;
Thread 2: int y = foo.x;
这是可能的y
为 0 或 257。由于原子性约束,它不会是任何其他值(例如 256 或 1)。但是,即使您知道在“挂断时间”中,线程 2 中的代码在线程 1 中的代码之后执行,也可能存在奇怪的缓存、内存访问“移动”等。x
挥发性将解决这个问题。
我会把剩下的事情留给真正诚实的专家。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)