Spring StopWatch并发

hub*_*blo 5 java concurrency spring stopwatch

我有一个Bean配置如下:

    @Bean(name = "myStopWatch")
    @Scope(value = "prototype")
    public MyStopWatch myStopWatch() {
       return new MyStopWatch();
    }
Run Code Online (Sandbox Code Playgroud)

而MyStopWatch类如下:

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();
       }
   }
}
Run Code Online (Sandbox Code Playgroud)

我们在高度并发的环境中使用这个bean.如果我的理解是正确的,那么MyStopWatch类永远不应该在线程之间共享,对吧?

但是,我们有时(很少)会收到以下错误:

java.lang.IllegalStateException:无法启动StopWatch:它已经在org.springframework.util.StopWatch.start(StopWatch.java:116)的org.springframework.util.StopWatch.start(StopWatch.java:127)上运行

到目前为止,我们无法通过测试重现此行为.我正在寻找有关如何正确定义我的sw变量(或ma bean)的更多信息,以避免此错误.

Syn*_*ync 1

你的假设是错误的。将 bean 声明为 并prototype不能确保线程安全。请参阅此答案以了解更多详细信息。

就使用 Spring 而言StopWatch文档指出它不是设计为线程安全的,也不适合在生产中使用。