ThreadLocal使用时因线程复用导致数据混乱分析
本文主要阐述使用ThreadLocal遇到数据混乱情况下的具体分析和解决过程
ThreadLocal原理
网上有很多介绍,不做详细介绍主要有四个方法:
1.get()方法是用来获取ThreadLocal在当前线程中保存的变量副本
2.set()用来设置当前线程中变量的副本
3.remove()用来移除当前线程中变量的副本
4.initialValue()是一个protected方法,一般是用来在使用时进行重写的
ThreadLocal使用场景
ThreadLocal与Synchronized区别?
Synchronized用于线程间的数据共享,通过对象的锁机制保证同一时间只有一个线程访问变量。
而ThreadLocal则用于线程间的数据隔离,为每一个线程提供一个独立的变量副本,从而隔离了多个线程对数据的访问冲突。
总结来说,对于多线程资源共享的问题,同步机制采用了“以时间换空间”的方式,而ThreadLocal采用了“以空间换时间”的方式。前者仅提供一份变量,
让不同的线程排队访问,而后者为每一个线程都提供了一份变量,因此可以同时访问而互不影响。
然而ThreadLocal场景一般用于数据库连接、session管理、上下文管理等。
不正确使用ThreadLocal导致数据混乱
public class ContextService {
private static final ThreadLocal<Context> CONTEXT_THREAD_LOCAL = new ThreadLocal<>();
public Context getContextInstance() {
if (CONTEXT_THREAD_LOCAL.get() == null) {
CONTEXT_THREAD_LOCAL.set(new Context());
}
return CONTEXT_THREAD_LOCAL.get();
}
public void initContext(Parameter parameter) {
//将其对象进行覆盖,防止使用ThreadLocal 线程池复用情况下,拿到同一个线程的对象
//CONTEXT_THREAD_LOCAL.set(new Context());
//CONTEXT_THREAD_LOCAL.set(buildContext(parameter));
Co