-1

我猜 JAXB 调用零参数构造函数,然后开始填充非易失性字段并将内容添加到列表中。

在我自己的代码中:在执行此操作(解组)后,生成的 bean 立即通过某些 add 方法被驱逐到一些工作线程,但不是通过构造函数或任何其他会触发内存模型刷新和重新获取数据的方式从共享区域。

这安全吗?还是 JAXB 在幕后做了一些魔术?我想不出在 java 编程语言中有任何方法可以强制所有线程对所有线程都可见。JAXB 生成的 bean 的用户是否必须担心在并发设置中可能没有明显设置字段?

编辑:为什么有这么多反对票?还没有人能够解释 JAXB 如何确保这项看似不可能完成的任务。

4

1 回答 1

3

我不会费心去调查你问题中的各种“事实”,我只是解释一下:

“没有参考就不是真的!”

这就是说,现在任何在 Java 中处理线程的人都必须真正尝试避免无意中建立发生之前发生后的关系。任何对 volatile 变量、同步块、Lock 对象或原子变量的使用都必然会建立这种关系。这会立即引入阻塞队列、同步哈希映射和许多其他零碎的东西。

您如何确定 JAXB 实现实际上会做错事?

也就是说,虽然从 JAXB 获得的对象在使用 JAXB 完成后与任何 Java 对象一样安全,但编组/解编组方法本身并不是线程安全的。我相信您不必担心,除非:

  • 您的线程共享 JAXB 处理程序对象。

  • 您在没有同步的情况下在线程之间传递对象:一种绝对不健康的做法,无论这些对象来自哪里......

编辑:

现在您已经编辑了您的问题,我们可以提供更具体的答案:

JAXB 生成的对象与任何其他 Java 对象一样是线程安全的,而这根本不是。直接构造函数调用本身也不提供线程安全性。如果没有建立之前发生的new关系,JVM 可以在调用时自由地返回部分初始化的对象。

一些方法,即通过使用 final 字段和不可变对象,可以避免这个陷阱,但是很难做到正确,尤其是使用 JAXB,而且它实际上并没有解决传播正确对象引用的问题,以便所有线程正在查看同一个对象。

底线:您可以通过使用适当的同步方法在线程之间安全地移动数据。不要假设任何关于底层实现的东西,除非有明确的记录。即使这样,最好还是安全地进行编码并进行防御性编码-无论如何,这通常会导致线程之间的交互更加清晰。如果在稍后阶段探查器指示性能问题,那么您应该开始考虑微调您的同步代码。

于 2012-03-25T23:58:53.057 回答