Spring 请求范围与 java 线程本地
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/25406157/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Spring Request scope vs java thread-local
提问by forhas
In high volume (~50,000 requests per second) java web-app I'm using ThreadLocal to execute a task which should be executed per request scope.
在大量(每秒约 50,000 个请求)java web-app 中,我使用 ThreadLocal 来执行一个应该在每个请求范围内执行的任务。
I could achieve the same effect using Spring request scope and I wondered which is better performance wise?
我可以使用 Spring 请求范围实现相同的效果,我想知道哪个性能更好?
In code, using ThreadLocal:
在代码中,使用 ThreadLocal:
private static final ThreadLocal<SomeClass> myThreadLocal = new ThreadLocal<SomeClass>();
And for each http request setting:
对于每个 http 请求设置:
myThreadLocal.set(new SomeClass());
Using Spring request scope:
使用 Spring 请求范围:
@Component
@Scope("request")
public class SomeClass{
...
}
Now, what will cost more:
现在,什么会花费更多:
myThreadLocal.get();
OR
或者
SpringContext.getBean(SomeClass.class);
I wonder if anyone has already tried such a benchmark?
我想知道是否有人已经尝试过这样的基准测试?
采纳答案by Bogdan Emil Mariesan
If we consider the traditional Java approach the answer can be deducted from the quote bellow as being much slower:
如果我们考虑传统的 Java 方法,可以从下面的引用中推断出答案要慢得多:
Because reflection involves types that are dynamically resolved, certain Java virtual machine optimizations can not be performed. Consequently, reflective operations have slower performance than their non-reflective counterparts, and should be avoided in sections of code which are called frequently in performance-sensitive applications.
由于反射涉及动态解析的类型,因此无法执行某些 Java 虚拟机优化。因此,反射操作的性能比非反射操作慢,应避免在对性能敏感的应用程序中频繁调用的代码段中使用。
Quoted from the JavaDoc about reflection - http://java.sun.com/docs/books/tutorial/reflect/index.html
引用自 JavaDoc 关于反射 - http://java.sun.com/docs/books/tutorial/reflect/index.html
So since Springuses Reflectionwith the getBean()
method the SpringContext.getBean(SomeClass.class);
approach should be slower.
因此,由于Spring将反射与该getBean()
方法一起使用,因此该SpringContext.getBean(SomeClass.class);
方法应该更慢。
EDIT:
编辑:
Also note that the ThreadLocal
also has caching embeddedso as long as you reuse information in those threads it's for sure faster.
另请注意,ThreadLocal
它还嵌入了缓存,因此只要您在这些线程中重用信息,它肯定会更快。
回答by Sotirios Delimanolis
The Spring solution will cost morebut will make for cleaner code IMO. There are a lot of steps involved in fetching, creating, initializing, and storing a bean. However you won't have to think about clearing the request scoped bean as you would the ThreadLocal
. It will be collected when the corresponding ServletRequest
is cleaned up.
Spring 解决方案将花费更多,但将使 IMO 代码更清晰。获取、创建、初始化和存储 bean 涉及许多步骤。但是,您不必像清除ThreadLocal
. ServletRequest
清理对应的时候会被收集。
回答by Artem Novikov
Regarding the ThreadLocal
solution I would like to add that there is probably a thread pool in your web server (for ex: Tomcat) and your thread local variable won't actually be cleared upon completion of each request as processing threads don't die with a thread pool enabled.
关于ThreadLocal
解决方案,我想补充一点,您的 Web 服务器中可能有一个线程池(例如:Tomcat),并且您的线程局部变量实际上不会在每个请求完成后被清除,因为处理线程不会因线程池启用。
You need to clear the thread-local variable (threadLocal.remove()
) manually upon complection of each request. For that you can use, for example, some kind of afterCompletion()
of some of those Spring request/response interceptors.
您需要threadLocal.remove()
在完成每个请求后手动清除线程局部变量 ( )。为此,例如,您可以使用afterCompletion()
某种 Spring 请求/响应拦截器。