Java 弹簧注射-螺纹安全

Java 弹簧注射-螺纹安全,java,spring,dependency-injection,thread-safety,Java,Spring,Dependency Injection,Thread Safety,如果我通过spring注入注入实例,它是线程安全的吗?如果没有,如何使其线程安全?我在谷歌上搜索,发现了相互矛盾的回答,无法得出任何结论。请给出建议。 提前谢谢。 -RW假设您已经创建了Test的单例实例,并试图从程序的另一部分设置/获取Spring(b)的值(a)。 在这种情况下,只需使get/set对同步: public class Test{ private First first; private Second second; public void setFirst(First fi

如果我通过spring注入注入实例,它是线程安全的吗?如果没有,如何使其线程安全?我在谷歌上搜索,发现了相互矛盾的回答,无法得出任何结论。请给出建议。 提前谢谢。
-RW

假设您已经创建了
Test
的单例实例,并试图从程序的另一部分设置/获取Spring(b)的值(a)。 在这种情况下,只需使get/set对同步:

public class Test{
private First first;
private Second second;

public void setFirst(First first){
this.first = first;
}
public First getFirst(){
 return first;
}
// same approach for second
}

我看不到多线程带来的其他不安全问题

如果您正在谈论我认为您正在谈论的内容,那么这是一个有趣的讨论

从技术上讲,由于
setFirst()
getFirst()
不是
同步的
,因此
setFirst()
可以在线程1上注入一个对象,而
getFirst()
可以在线程2上返回另一个对象。正如他们所说,Java内存模型保留使其“最终一致”的权利

因此,在Spring的情况下,它在启动期间配置其bean图(或服务器的内部启动线程),HTTP请求线程(例如)可能由于缺乏同步而无法正确地看到该bean图

注意:这与并发访问无关。即使HTTP请求在Spring初始化之后进入,Java内存模型也不能保证这些线程将看到正确的数据

实际上,这种情况从未发生过(至少,我从未见过这种情况发生过)。缺少同步实际上只是并发线程的一个问题,这不是这里的问题

所以这实际上只是一个学术争论


如果这不是你说的,我道歉。不过,这仍然是一个有趣的想法。

依赖项的注入是由Spring处理的,您不应该关心getter和setter的线程安全性,因为Spring将注入依赖项,因为您没有同步逻辑

此外,在完全配置上下文和注入所有依赖项之前,其他线程(即应用程序的线程)不会使用bean


您不应该担心依赖项注入的线程安全性,Spring会这样做(很可能Spring只使用一个线程来注入所有依赖项)。

您的问题太模糊了。什么意思?给出更好的例子,以及为什么您认为它可能不是线程安全的。请澄清您的问题。您显示的类始终是线程安全的,因为它不允许对其状态进行任何访问(除了使用
setAccessible()
的肮脏攻击)。像这样同步您的方法是最糟糕的事情。首先,您没有保护您的this。首先,无论如何,您只是确保一次只有一个线程可以进入setFirst和getFirst方法,这是毫无意义的。@Spajus-仔细阅读我的前提条件。使用
synchronize(this)
确保在读取this.first的值时不会修改它。根据java规范,分配不被授予原子操作。因此,对于某些平台,可能会修改this.first的一些字节,而有些则不会。(例如,您可以在google上搜索术语“breaked pattern”,它在java中完全是因为非原子的赋值而被破坏的)@spajus-这个类将被Concurrent请求(即多线程)使用。我们需要注意这个吗?我在谷歌上找到了这个链接,[url](blog.webscale.co.in/?p=64)。有什么建议吗?@rock wells-我不是@spajus,但我知道答案。在指定的文章中创建ben显示了非常奇怪的问题,当您以并行方式尝试从代码和Spring上下文设置singleton时。通常它是异国情调的,因为如果你这么做了,那你为什么需要春天呢?在正确的体系结构和正确的Spring用法中,bean的创建可能是不安全的,而且不会破坏任何逻辑。但是这些bean实例的使用应该是同步的,所以不管(-2)我坚持,get/set都应该是安全的。我们需要注意这个吗?我在谷歌上找到了这个链接。有什么建议吗?引用Java Concurrency在实践中的一句话,“如果多个线程在没有适当同步的情况下访问同一个可变状态变量,那么您的程序就坏了”。因此,该类必须是线程安全的,或者以线程安全的方式使用,而不管它是如何实例化/注入的。Spring(可能)只使用一个线程来构造它的bean图,所以这部分是安全的。但是,这并不意味着以后其他线程可以看到所有内容(内存可见性)。所以你必须关心线程的安全性——Spring不关心这一点。
public synchronized void setFirst(First first){
    this.first = first;
}
public synchronized First getFirst(){
    return first;
}