Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Request scope vs java thread-local

Tags:

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.

I could achieve the same effect using Spring request scope and I wondered which is better performance wise?

In code, using ThreadLocal:

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

And for each http request setting:

myThreadLocal.set(new SomeClass()); 

Using Spring request scope:

@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?

like image 477
forhas Avatar asked Aug 20 '14 13:08

forhas


2 Answers

If we consider the traditional Java approach the answer can be deducted from the quote bellow as being much slower:

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.

Quoted from the JavaDoc about reflection - http://java.sun.com/docs/books/tutorial/reflect/index.html

So since Spring uses Reflection with the getBean() method the SpringContext.getBean(SomeClass.class); approach should be slower.

EDIT:

Also note that the ThreadLocal also has caching embedded so as long as you reuse information in those threads it's for sure faster.

like image 149
Bogdan Emil Mariesan Avatar answered Sep 21 '22 06:09

Bogdan Emil Mariesan


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.

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.

like image 40
Artem Novikov Avatar answered Sep 23 '22 06:09

Artem Novikov