首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Inject (@Inject)字段是否安全发布?

Inject (@Inject)字段是否安全发布?
EN

Stack Overflow用户
提问于 2012-12-13 16:43:03
回答 4查看 1.4K关注 0票数 9

当我在类中使用字段注入时,如下所示:

代码语言:javascript
复制
@Inject
private MyClass myField;

我能对这个领域的"safe publication“状态做任何假设吗?或者换个说法,假设MyClass本身是线程安全的,那么在使用这个字段时是否存在任何并发风险?

我的本能通常是在可能的情况下最终创建所有字段,但这并不适用于字段注入。当然,我可以使用构造函数注入,但是我通常不得不创建一个额外的“假”非args构造函数,仅仅是为了代理。问题不大,但是使用字段注入就更方便了。另一种选择可能是将字段标记为易失性(甚至使用锁定),但这真的有必要吗?

JSR-299规范似乎没有回答这个问题。我在像Weld这样的实现上使用CDI。

  • 我正在注入的对象将由多个线程使用(例如@ApplicationScoped )。我想要这个。
  • 我知道,如果MyClass是不变的,安全的发布就不是一个问题。但我不一定只注入不可变的对象。
  • MyClass本身被认为是线程安全的;这不是我关心的问题。这种担心严格地说是关于不安全的发布,例如,由于Java模型的规则,线程可能会看到MyClass的半构造实例。
EN

回答 4

Stack Overflow用户

发布于 2013-06-28 13:39:24

可能这种情况下的线程安全被故意从规范中忽略了,这意味着线程安全没有得到保证。

让我们想想:如果一个线程编写的字段被另一个线程读取,除非发生某种形式的关系,否则另一个线程可能读取陈旧的数据。Guice最终使用反射来设置myField的值,或者使用自动生成的setter。在字段读取或方法调用之前,没有发生--在关系之前发生反射-写入--在字段读取之前(除非使用了锁、挥发物或其他构成发生前关系的方法)。

因此,我要说,看到空值的可能性(可能相当低)。

编辑:根据http://bit.ly/1m4AUIz,在构造函数结束后(通过反射)写入最终字段与在构造函数中初始化字段具有相同的语义。因此,将Guice注入的字段设置为null,并使其正确工作。这确实是一个非常黑暗的JVM角:-)此外,根据http://bit.ly/1m4AwJU,Guice只在一个线程中执行注入,这使得它是线程安全的.在我看来很奇怪,但显然是这样的。

票数 3
EN

Stack Overflow用户

发布于 2013-07-03 04:30:12

我相信您可以基于java内存模型的9.1.1部分:http://www.cs.umd.edu/~pugh/java/memoryModel/jsr133.pdf 9.1.1最终字段的构造修改.最终字段的冻结发生,既发生在设置最终字段的构造函数的末尾,也发生在通过反射其他特殊机制对最终字段进行每次修改之后立即发生。..。

一些相关的Guice讨论是:http://markmail.org/message/fxs5k32dihpoy5ry#query:bob%20lee%20constructor%20injection+page:1+mid:fxs5k32dihpoy5ry+state:results

。。和id=52252#284713

不过,如果DI框架能做出这种明确的声明,那就太好了。

票数 2
EN

Stack Overflow用户

发布于 2012-12-14 08:08:39

我总是使用构造函数注入。那么您的字段可能是最终的,并且它们的线程安全是毫无疑问的。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13864443

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档