簡體   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