Issue
Currently, I have a web project. I save a variable like sessionid in threadlocal in an Interceptor of SpringMVC and remove it in postHandle method. But I'm wondering if this is safe or not. ex. if a thread saved a sessionid, then CPU context switch happened, in this case, something else will take this thread and set another sessionid or remove it at postHandle. When we switch back, the sessionid changed. If this is possible, do we have some other solutions?
@Interceptor
public class BusinessInterceptor extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
Object handler) throws Exception {
ThreadLocalUtil.contextThreadLocal.set(createSessionId());
return true;
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response,
Object handler, Exception ex)
throws Exception {
ThreadLocalUtil.contextThreadLocal.remove();
}
}
Solution
You are getting a bit confused by the meaning of Context Switch. Just from a look at Wikipedia, it is defined as:
In a multitasking context, it refers to the process of storing the system state for one task, so that task can be paused and another task resumed.
Where storing the system state for one task means storing all the values a thread has access to, which of course includes thread-locals. Context-Switching is therefore about sharing CPU-time, not about sharing data across threads. (Well, yes, there is also Context-Switching when the OS moves from user mode to kernel mode, but I guess that is not the one kind the OP has in his mind).
Furthermore, thread-locals will hold a different value depending on the thread that has access to it. If we look at the definition of ThreadLocal
in Java:
These variables differ from their normal counterparts in that each thread that accesses one (via its
get
orset
method) has its own, independently initialized copy of the variable.
So, the answer is: No, no other thread would be able to read the value of that thread-local variable, independently of the number of context switches that are happening.
In a different note, I would be worried about the assumption that you are making in your code. I mean, storing a value in a thread-local on every request makes me think that you are assuming a single thread per request execution model. Also, relying on the usage of thread-local variables to pass around values is the equivalent to use global variables, but with the twist that they aren't more like partially-global variables and usually come along with funny surprises at runtime.
You must be aware that in this time an age in which we have asynchronous/reactive execution models, HTTP/2, etc., your assumption will fall flat since you will have more than one thread executing a given request... and because of that, your thread-local variable will either be uninitialized or hold a totally unexpected value when any other thread tries to access it. And this will come with a lot of headaches.
I would recommend you to find a different way of passing around your session ID, and I would recommend you do it explicitly as a parameter to subsequent functions that may need it.
Answered By - Alonso Dominguez