Java 多线程和安全发布

标签 java multithreading safe-publication

<分区>

看完“Java concurrent in practice”和“OSGI in practice”后,我发现一个特定的主题非常有趣;安全出版物。以下来自JCIP:

To publish an object safely, both the reference to the object and the object's state must be made visible to other threads at the same time. A properly constructed object can be safely published by:

  • Initializing an object reference from a static initializer.
  • Storing a reference to it into a volatile field.
  • Storing a reference to it into a final field.
  • Storing a reference to it into a field that is properly guarded by a (synchronized) lock.

我的第一个问题:有多少 java 开发人员知道这个(问题)? 有多少真实世界的 Java 应用程序真正遵循这个,这真的是一个真正的问题吗?我有一种感觉,99% 的已实现的 JVM 都不是那么“邪恶”,即不能保证线程(实际上它实际上(几乎)“不可能”)看到陈旧数据只是因为引用没有遵循上面的“安全发布习语”。

最佳答案

按比例来说,可以公平地说,很少有程序员充分理解同步和并发。谁知道现在有多少服务器应用程序管理金融交易、医疗记录、警察记录、电话等,这些应用程序充满了同步错误,基本上是偶然工作的,或者非常非常偶尔地失败(从来没有听说过有人得到幻影电话费添加到他们的电话费中?),原因从未真正调查过或深究过。

对象发布是一个特殊的问题,因为它经常被忽视,编译器在这个地方进行优化很合理,如果您不知道它可能会导致意外行为:在 JIT 编译的代码中,存储一个指针,然后递增它并存储数据是一件非常合理的事情。您可能认为它是“邪恶的”,但在低级别上,它确实是您期望 JVM 规范的样子。 (顺便说一下,我听说在 JRockit 中运行的真实程序遇到了这个问题——这不仅仅是理论上的。)

如果您知道您的应用程序存在同步错误,但在您当前硬件上的当前 JVM 中没有出现异常行为,那么 (a) 恭喜; (b),现在是开始“冷静地走向安全导出”的时候了,在您需要升级太多组件之前修复您的代码并教育您的程序员。

关于Java 多线程和安全发布,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3869016/

相关文章:

java - Hibernate:添加到列表的实体的ID

java - 内存映射文件 : pros and cons?

c++ - 当 Execute() 在 C++ Builder 中终止时,不调用 OnTerminate() 方法

node.js - NodeJS到底是如何处理高并发请求的?

java - 没有状态的对象在发布时总是可见吗?

java - 为不安全发布的 java.lang.String 提供恢复时间

java - spring mvc中如何使用静态资源?

.net - 在 onconnect 例程中调用 winform 时出错

java - Java 解析字符串为 Date