Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring StopWatch concurrency

I have a Bean configured as follow:

    @Bean(name = "myStopWatch")
    @Scope(value = "prototype")
    public MyStopWatch myStopWatch() {
       return new MyStopWatch();
    }

And MyStopWatch class is as follow:

import org.springframework.util.StopWatch;

public class MyStopWatch {

   private StopWatch sw = new StopWatch();

   public void start() {
       if(!sw.isRunning()) {
           sw.start();
       }
   }

   public void stop() {
       if(sw.isRunning()) {
           sw.stop();
       }
   }
}

We're using this bean in a highly concurrent environment. If my understanding is correct, MyStopWatch class should never be shared bewtween thread, right?

However, we sometimes (very rarely) get the following error:

java.lang.IllegalStateException: Can't start StopWatch: it's already running at org.springframework.util.StopWatch.start(StopWatch.java:127) at org.springframework.util.StopWatch.start(StopWatch.java:116)

So far we couldn't reproduce this behavior with our test. I'm looking for more information regarding how I should correctly define my sw variable (or ma bean) in order to avoid this error.

like image 437
hublo Avatar asked Nov 08 '22 13:11

hublo


1 Answers

Your assumption is wrong. Declaring a bean as prototype does not ensure thread safety. Please see this answer for more details.

As far as using Spring's StopWatch goes, the documentation states that it is not designed to be thread-safe and is also not meant to be used in production.

like image 103
Sync Avatar answered Nov 15 '22 05:11

Sync