简体   繁体   中英

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

We are using a mail-service in my web application (Jetty). The service object is injected using spring beans at run-time.

Now, the service is not thread-safe. How can we handle this? On reading through some of the posts here I found following options. Please let us know the pros & cons of the following.

  1. Synchronize methods inside mail service (Will it be good in the context of web-app?)
  2. Create new object everytime - This will also be expensive as initialization and release take time
  3. Object Pool
  4. ThreadLocal - One service object per thread

Spring config:

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

Java Bean

@Autowired
MailService mailService;
  1. Synchronize methods inside mail service.
    Synchronizing through blocking can slow down application, depends on execution time of synchronized block. If it's a singleton bean, calls to MailService will be executed sequentially. Even if it's a prototype bean, it still can be called from different threads simultaneously and will lead to sequential execution.

  2. Create new object everytime. If it doesn't consume significant time and resources, it's a good solution. Create new objects as local variable in methods, they will not be shared between threads.

  3. ThreadLocal. Powerful concept, but has own problems:

    • variables can be accessed everywhere and this violates incapsulation. Can lead to practices like grabbing HttpServletRequest from ThreadLocals in your DAO objects.
    • easy to introduce a memory leak. If one of the application classes stores a value in ThreadLocal variable and doesn't remove it after the task at hand is completed, a copy of that Object will remain with the Thread (from the application server thread pool). Since lifespan of the pooled Thread surpasses that of the application, it will prevent the object and thus a ClassLoader being responsible for loading the application from being garbage collected. And we have created a leak, which has a chance to surface in a good old java.lang.OutOfMemoryError: PermGen space form.
      We should avoid using ThreadLocal if possible considering the harm it can cause.
  4. Object pool. I root for this solution. Thread-safety in this case can be achieved by writing a new thread-safe optimized silgleton wrapper bean, which in this case will contain MailService objects pool. Wrapper can be safely accessed from any thread and it redirects execution down to the pool. Here is an example.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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