当我在类中使用字段注入时,如下所示:
@Inject
private MyClass myField;我能对这个领域的"safe publication“状态做任何假设吗?或者换个说法,假设MyClass本身是线程安全的,那么在使用这个字段时是否存在任何并发风险?
我的本能通常是在可能的情况下最终创建所有字段,但这并不适用于字段注入。当然,我可以使用构造函数注入,但是我通常不得不创建一个额外的“假”非args构造函数,仅仅是为了代理。问题不大,但是使用字段注入就更方便了。另一种选择可能是将字段标记为易失性(甚至使用锁定),但这真的有必要吗?
JSR-299规范似乎没有回答这个问题。我在像Weld这样的实现上使用CDI。
发布于 2013-06-28 13:39:24
可能这种情况下的线程安全被故意从规范中忽略了,这意味着线程安全没有得到保证。
让我们想想:如果一个线程编写的字段被另一个线程读取,除非发生某种形式的关系,否则另一个线程可能读取陈旧的数据。Guice最终使用反射来设置myField的值,或者使用自动生成的setter。在字段读取或方法调用之前,没有发生--在关系之前发生反射-写入--在字段读取之前(除非使用了锁、挥发物或其他构成发生前关系的方法)。
因此,我要说,看到空值的可能性(可能相当低)。
编辑:根据http://bit.ly/1m4AUIz,在构造函数结束后(通过反射)写入最终字段与在构造函数中初始化字段具有相同的语义。因此,将Guice注入的字段设置为null,并使其正确工作。这确实是一个非常黑暗的JVM角:-)此外,根据http://bit.ly/1m4AwJU,Guice只在一个线程中执行注入,这使得它是线程安全的.在我看来很奇怪,但显然是这样的。
发布于 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框架能做出这种明确的声明,那就太好了。
发布于 2012-12-14 08:08:39
我总是使用构造函数注入。那么您的字段可能是最终的,并且它们的线程安全是毫无疑问的。
https://stackoverflow.com/questions/13864443
复制相似问题