Spring 秒表并发
Spring StopWatch concurrency
我有一个 Bean 配置如下:
@Bean(name = "myStopWatch")
@Scope(value = "prototype")
public MyStopWatch myStopWatch() {
return new MyStopWatch();
}
MyStopWatch class如下:
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();
}
}
}
我们在高度并发的环境中使用这个 bean。如果我的理解是正确的,MyStopWatch class 不应该在线程之间共享,对吗?
但是,我们有时(很少)会收到以下错误:
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)
到目前为止,我们无法通过测试重现此行为。我正在寻找有关如何正确定义 sw 变量(或 ma bean)以避免此错误的更多信息。
你的假设是错误的。将 bean 声明为 prototype
并不能确保线程安全。请参阅 this answer 了解更多详情。
就使用 Spring 的 StopWatch
而言,the documentation 指出它并非设计为线程安全的,也不打算在生产中使用。
首先,它不是线程安全的,文档中是这样说的。将你的 bean 作为 prototype
并不意味着不能有多个线程同时更新它,它只是意味着当你请求这样一个 bean 时 - 一直返回一个新实例(当使用 getBean
或 @Autowired
例如)。
如果您想测量经过的时间(做某事花费了多少时间),请远离 Spring 中的 StopWatch
。如果你有番石榴,它也有一个 StopWatch
- 使用它(它仍然不是线程安全的),否则在你想要分析的代码的每个部分中一个简单的 System.nanoTime
就足够了。
我有一个 Bean 配置如下:
@Bean(name = "myStopWatch")
@Scope(value = "prototype")
public MyStopWatch myStopWatch() {
return new MyStopWatch();
}
MyStopWatch class如下:
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();
}
}
}
我们在高度并发的环境中使用这个 bean。如果我的理解是正确的,MyStopWatch class 不应该在线程之间共享,对吗?
但是,我们有时(很少)会收到以下错误:
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)
到目前为止,我们无法通过测试重现此行为。我正在寻找有关如何正确定义 sw 变量(或 ma bean)以避免此错误的更多信息。
你的假设是错误的。将 bean 声明为 prototype
并不能确保线程安全。请参阅 this answer 了解更多详情。
就使用 Spring 的 StopWatch
而言,the documentation 指出它并非设计为线程安全的,也不打算在生产中使用。
首先,它不是线程安全的,文档中是这样说的。将你的 bean 作为 prototype
并不意味着不能有多个线程同时更新它,它只是意味着当你请求这样一个 bean 时 - 一直返回一个新实例(当使用 getBean
或 @Autowired
例如)。
如果您想测量经过的时间(做某事花费了多少时间),请远离 Spring 中的 StopWatch
。如果你有番石榴,它也有一个 StopWatch
- 使用它(它仍然不是线程安全的),否则在你想要分析的代码的每个部分中一个简单的 System.nanoTime
就足够了。