【问题标题】:When multiple access Spring Singleton instance at same time多个同时访问 Spring Singleton 实例时
【发布时间】:2011-06-04 18:48:57
【问题描述】:

如果您在 spring 配置中在单例范围内定义您的服务,如果多个用户同时尝试访问它(即作为依赖注入到您的控制器中)会发生什么?它应该引起任何冲突吗?还是 IoC 容器会保留后面的调用,直到第一个调用完成?如果是这样,它应该会降低大型应用程序的性能,这对我来说听起来不对。谁能给我一个正确的答案?

顺便说一句,我记得,如果它不是单例的,IoC 容器将根据请求的数量汇集几个实例。有人可以确认吗?

【问题讨论】:

    标签: spring ioc-container


    【解决方案1】:

    如果多个用户同时尝试访问它(即作为依赖注入到您的控制器中)会发生什么?

    一个单例 bean 可以同时访问很多次。这就是为什么它总是必须是线程安全的

    会不会引起冲突?

    仅当您未能使其成为线程安全时

    或者 IoC 容器将保持后面的调用直到第一个调用完成?

    不,那会很糟糕


    顺便说一句,我记得,如果它不是单例的,IoC 容器将根据请求的数量汇集几个实例。有人可以确认吗?

    Spring 有以下作用域 (see Bean Scopes reference):

    • singleton(每个应用只管理一个实例)
    • prototype(每次注入一个新实例)
    • session(每个 HTTP 会话一个实例,仅在 Spring MVC 中)
    • request(每个 HTTP 请求一个实例,仅在 Spring MVC 中)
    • global session(每个全局 HTTP 会话一个实例,仅在基于 portlet 的 Spring MVC 中)

    还有:

    从 Spring 3.0 开始,线程范围可用,但默认情况下未注册。有关详细信息,请参阅SimpleThreadScope 的文档。

    你描述的是一个对象池。在 Spring 中,它将被实现为原型范围的 FactoryBean。在内部,它会使用像 Apache Commons / Pool 这样的库。

    【讨论】:

    • 感谢您的回复。使单例类线程安全的最佳实践是什么?我不认为使用同步块是一个好主意,因为它对性能来说太昂贵了。
    • @Brolinuk 有时您需要同步块,有时则不需要。阅读Java Concurrency in Practice 以获取更多参考。基本上:如果你没有可变状态,你通常是线程安全的。如果这样做,您将需要一些方法来同步对可变状态的访问。还有一个relevant SO question
    【解决方案2】:

    单身人士就是这样 - 单身人士。一个实例由 Spring 上下文管理,所有请求同时通过该实例。让线程安全由您决定。

    如果您的 bean 不是线程安全的,那么请考虑使用非单例范围的 bean。 Spring 允许您使用请求、会话和原型范围。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-03-23
      • 2013-04-13
      • 2012-06-12
      • 1970-01-01
      • 1970-01-01
      • 2014-08-11
      • 2015-01-25
      • 1970-01-01
      相关资源
      最近更新 更多