Java SpringBean中线程安全的处理方法及其优缺点;欺骗

Java SpringBean中线程安全的处理方法及其优缺点;欺骗,java,spring,multithreading,jetty,Java,Spring,Multithreading,Jetty,我们正在我的web应用程序(Jetty)中使用邮件服务。服务对象在运行时使用Springbean注入 现在,该服务不是线程安全的。我们如何处理这件事?通过阅读这里的一些帖子,我发现了以下选项。请让我们知道下面的优点和缺点 同步邮件服务内部的方法(在web应用程序上下文中是否良好?) 每次都要创建新对象-由于初始化和发布需要时间,这也会很昂贵 对象池 ThreadLocal-每个线程一个服务对象 弹簧配置: <bean id="mailService" class="com.....M

我们正在我的web应用程序(Jetty)中使用邮件服务。服务对象在运行时使用Springbean注入

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

  • 同步邮件服务内部的方法(在web应用程序上下文中是否良好?)
  • 每次都要创建新对象-由于初始化和发布需要时间,这也会很昂贵
  • 对象池
  • ThreadLocal-每个线程一个服务对象
  • 弹簧配置:

       <bean id="mailService" class="com.....MailService">
         <property name="mailSender" ref="mailSender" />
         <property name="registrationEmailMessage" ref="registrationEmail" />
         ...
       </bean>
    
  • 同步邮件服务中的方法
    通过阻塞进行同步会降低应用程序的速度,这取决于同步块的执行时间。如果它是一个
    singleton
    bean,那么对
    MailService
    的调用将按顺序执行。即使它是一个
    原型
    bean,它仍然可以从不同的线程同时调用,并将导致顺序执行

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

  • ThreadLocal。强大的概念,但有自己的问题:

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

  • @Autowired
    MailService mailService;