繁体   English   中英

在Spring bean中处理线程安全的方法及其优点和缺点

[英]Ways to handle thread-safety in spring beans and their pros & cons

我们在我的Web应用程序(Jetty)中使用了邮件服务。 服务对象在运行时使用spring bean注入。

现在,该服务不是线程安全的。 我们该如何处理? 通过阅读这里的一些帖子,我发现了以下选择。 请让我们知道以下优点和缺点。

  1. 同步邮件服务中的方法(在Web应用程序的上下文中会很好吗?)
  2. 每次创建新对象-由于初始化和发布需要时间,因此这也会很昂贵
  3. 对象池
  4. ThreadLocal-每个线程一个服务对象

春季配置:

   <bean id="mailService" class="com.....MailService">
     <property name="mailSender" ref="mailSender" />
     <property name="registrationEmailMessage" ref="registrationEmail" />
     ...
   </bean>

Java豆

@Autowired
MailService mailService;
  1. 同步邮件服务中的方法。
    通过阻塞同步可能会减慢应用程序的速度,具体取决于同步块的执行时间。 如果是singleton bean,则将按顺序执行对MailService调用。 即使它是prototype bean,仍然可以同时从不同的线程中调用它,并将导致顺序执行。

  2. 每次创建新对象。 如果它不消耗大量时间和资源,那是一个很好的解决方案。 在方法中创建新对象作为局部变量,它们将不会在线程之间共享。

  3. ThreadLocal的。 功能强大的概念,但有自己的问题:

    • 变量可以在任何地方访问,这违反了封装。 可能导致诸如从DAO对象中的ThreadLocals捕获HttpServletRequest之类的实践。
    • 容易造成内存泄漏。 如果其中一个应用程序类将一个值存储在ThreadLocal变量中,并且在手头的任务完成后没有将其删除,则该Object的副本将与Thread一起保留(来自应用程序服务器线程池)。 由于池化线程的寿命超过了应用程序的寿命,因此它将防止该对象,从而使ClassLoader负责加载应用程序而不会被垃圾回收。 而且我们创建了一个泄漏,有机会以一种很好的旧java.lang.OutOfMemoryError:PermGen空间形式浮出水面。
      考虑到可能造成的危害,应尽可能避免使用ThreadLocal。
  4. 对象池。 我支持该解决方案。 在这种情况下,可以通过编写新的线程安全优化的silgleton包装器bean来实现线程安全,在这种情况下,它将包含MailService对象池。 可以从任何线程安全地访问包装器,并且包装器将执行重定向到池中。 是一个例子。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM