Spring对象是线程安全的吗?如果没有,如何使它们线程安全?
这是两个不相关的问题:
spring线程安全吗? 没有。
Spring具有不同的bean 作用域(例如Prototype,Singleton等),但是所有这些作用域都是在创建bean 时强制执行的。例如,每次“注入”一个“原型”范围的bean都会被创建,而一个“单个”范围的bean将被创建一次并在应用程序上下文中共享。还有其他的范围,但他们只是一个限定的时间跨度(如“范围”)时,一个新的实例将被创建。
以上内容与线程安全无关,因为如果多个线程可以访问一个bean(无论范围如何),那么它仅取决于该bean 的设计是否为“线程安全”。 。
我之所以说“很少,如果有的话”是因为它可能取决于你要解决的问题。例如,如果你担心两个或多个HTTP请求是否可能为同一个bean产生问题,则存在一个“请求”作用域,它将为每个HTTP请求创建一个新的bean实例,因此你可以“考虑”一个在多个HTTP请求的上下文中,特定的bean是“安全的”。但是,Spring仍然不是真正的线程安全的,因为如果多个线程在同一个 HTTP请求中使用此bean ,它将返回到bean设计(你的bean支持类设计)。
如何使/设计线程安全的“对象”?
有几种方法,可能在这里列出太久了,但是这里有一些示例:
将你的bean设计为不可变的:例如,没有设置方法,仅使用构造函数参数来创建bean。还有其他方法,例如Builder模式等。
将你的bean设计为无状态的:例如,执行某项操作的bean 可能只是一个函数(或多个函数)。在大多数情况下,该bean可以并且应该是无状态的,这意味着它没有任何状态,它仅使用你每次(每次调用)提供的函数参数来执行操作
设计你的bean 持久性:这是“不可变”的特例,但具有一些非常好的属性。通常在函数式编程中使用,其中Spring(至少到目前为止)没有在命令式环境中有用,但是我将它们用于Scala / Spring项目。
设计带有锁的bean [不得已]:除非你正在使用较低级别的库,否则我建议你不要这样做。原因是我们(人类)对锁的想法不好。就像我们成长和培养的方式一样。一切并行进行,而无需我们“暂停下雨,让我打伞”。但是,当你“同时谈论多个事情”时,计算机都是关于锁的,因此我们中的某些人(特殊人士)正在公平地分享并基于这些锁实现库。其他大多数人都可以使用这些库,而不必担心并发性。