繁体   English   中英

Spring请求范围vs java thread-local

[英]Spring Request scope vs java thread-local

在大量(每秒约50,000个请求)java web-app我正在使用ThreadLocal来执行应该按请求范围执行的任务。

我可以使用Spring请求范围实现相同的效果,我想知道哪个性能更好?

在代码中,使用ThreadLocal:

private static final ThreadLocal<SomeClass> myThreadLocal = new ThreadLocal<SomeClass>();

并为每个http请求设置:

myThreadLocal.set(new SomeClass());

使用Spring请求范围:

@Component
@Scope("request")
public class SomeClass{
...
}

现在,会花多少钱:

myThreadLocal.get();

要么

SpringContext.getBean(SomeClass.class);

我想知道是否有人已经尝试过这样的基准测试?

如果我们考虑传统的Java方法,答案可以从下面的引用中减去,因为它要慢得多:

由于反射涉及动态解析的类型,因此无法执行某些Java虚拟机优化。 因此,反射操作的性能低于非反射操作,并且应避免在性能敏感应用程序中频繁调用的代码段中。

引自JavaDoc的反思 - http://java.sun.com/docs/books/tutorial/reflect/index.html

所以,因为Spring使用了反射getBean()方法的SpringContext.getBean(SomeClass.class); 方法应该更慢。

编辑

另请注意, ThreadLocal嵌入了缓存 ,只要您在这些线程中重复使用信息肯定会更快。

关于ThreadLocal解决方案,我想补充一点,您的Web服务器中可能存在一个线程池(例如:Tomcat),并且在完成每个请求后,您的线程局部变量实际上不会被清除,因为处理线程不会死已启用线程池。

您需要在threadLocal.remove()每个请求时手动清除线程局部变量( threadLocal.remove() )。 为此,您可以使用某些Spring请求/响应拦截器的某种afterCompletion()

Spring解决方案的成本会更高,但会使IMO更清晰。 获取,创建,初始化和存储bean涉及许多步骤。 但是,您不必像ThreadLocal那样考虑清除请求范围的bean。 清除相应的ServletRequest时将收集它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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