当前位置:网站首页>ThreadLocal encountered data problems in thread pool and Solutions
ThreadLocal encountered data problems in thread pool and Solutions
2022-07-22 20:55:00 【Program ape Dongxiao】
ThreadLocal Commonly used in development , adopt ThreadLocal Operate data to realize the isolation between threads , Ensure that data security problems will not be caused by operating the same data between threads . But this isolation has a scope , That is to say, in some specific cases, there will still be data security problems . In this particular case, the thread pool is used , And in ThreadLocal No data cleaning before and after use , It will lead to safety problems , Let's take a look at the situation and how to solve it .
ThreadLocal Normal use
One main Method , Create a new thread as the simulation thread , Simultaneous operation ThreadLocal, By printing the corresponding output value ThreadLocal The role of .
public class ThreadLocalDemo {
private static ThreadLocal<Integer> local = new ThreadLocal<>();
public static void main(String[] args) {
local.set(1);
System.out.println(Thread.currentThread().getName() + "===>" + local.get());
operateLocal();
// Simulate another thread
new Thread(() -> {
System.out.println(Thread.currentThread().getName() + "===>" + local.get());
local.set(4);
System.out.println(Thread.currentThread().getName() + "===>" + local.get());
operateLocal();
}).start();
}
private static void operateLocal() {
Integer value = local.get();
local.set(++value);
System.out.println(Thread.currentThread().getName() + "===>" + local.get());
}
}
Output result :
main===>1
main===>2
Thread-0===>null
Thread-0===>4
Thread-0===>5
We can know from the result , There is no interference between the two threads , Operate the data in their own space , Thread safety is achieved . This is also used in normal use . It is thread safe for this method alone , Data is also safe , But let's take a look at the scenarios where problems will occur .
Thread pool ThreadLocal
Create a thread pool here , For the convenience of simulation , Only one thread is created in the thread pool , And then through ExecutorService
Twice yes ThreadLocal To operate , You will find a problem .
public class ThreadLocalDemo {
private static ThreadLocal<Integer> local = new ThreadLocal<>();
public static void main(String[] args) throws InterruptedException {
ExecutorService executorService = Executors.newSingleThreadExecutor();// Thread pool
executorService.execute(() -> {
//1
local.set(123);
System.out.println(Thread.currentThread().getName() + "==>" + local.get());
});
executorService.execute(() ->//2
System.out.println(Thread.currentThread().getName() + "==>" + local.get())
);
executorService.shutdown();
}
}
In code block 1 towards ThreadLocal The added value is 123, Then print out the corresponding thread name and ThreadLocal The value stored in it . Then in the code block 2 From inside ThreadLocal Get value inside . The output is as follows :
pool-1-thread-1==>123
pool-1-thread-1==>123
The output content of the two positions is the same , That means when using thread pool , The data set by a thread may remain ThreadLocal Inside , When the next thread uses it, it may directly get the residual data of the previous operation , Lead to data pollution .
What we need to know here is , In many blogs ( Of course, it includes some blogs I reprint ) All say ThreadLocal Inside ThreadLocalMap The key of is weak connection , Next time GC When recycling, it will be recycled automatically , There will be no data security problems . But this statement has a specific scenario , That is, after the execution of the current thread ends ,ThreadLocal The object needs to be manually set to null. because GC It's not always implemented , It needs to meet certain conditions , So there is a lag .
In the use of ThreadLocal For thread safety , Basically, they are placed in member variables , Set the end of each execution to null If you don't pay attention to your operation, you won't do it , Or miss , Another trouble this brings is that you have to new Create a ThreadLocal, It always feels awkward .
To sum up :
- GC Execution requires conditions that cannot be executed immediately after the execution of the current thread , Clean up ThreadLocal The data stored inside
- Even if GC Trigger , stay ThreadLocal Strong connection established by external member variables , It can't be cleaned up
- At the end of each execution null Assign to member variable , At the beginning of execution , Manual initialization ThreadLocal
The proposed solution
Thread pool and ThreadLocal Not at the same time
This seems a little ridiculous , The thread pool is in the normal one java Will be used in the project , In other words, give up ThreadLocal I don't need it now . So this solution is too extreme .
clear ThreadLocal data
This is the best method I have thought of at present , You can use aspect oriented thinking , Cut into using ThreadLocal Methods , Before method execution 、 After execution 、 When throwing an exception ThreadLocal Perform data cleaning .
Sample code :
public static void main(String[] args) {
local.remove();// clear
try {
//……
} catch (Exception e) {
//……
} finally {
local.remove();// clear
}
}
It's just demo Example , There is no specific business content , There is no specific implementation according to the aspect , Lazy , Just ideas .
summary
In the use of ThreadLocal You should still pay attention to it , Although in ThreadLocal Weak connection mechanism has been used to connect with GC The recovery of weak connections to achieve timely data recovery , In actual development , There are still some problems , So we can't rely entirely on ThreadLocal, Still need to think in many ways , Be rigorous . I didn't think of this problem before , Used in business code , As a result, my colleagues reminded me when they saw my code ( On the importance of having a group of good comrades in arms ).
边栏推荐
猜你喜欢
随机推荐
Automatic current mirror layout (acml) tool
Performance perception of transistor arrays in analog circuits common centroid layout and wiring align
postman接口测试
结构体和联合体
尾插法构造链表
Commonly used operators of spark
Multithreading 03 -- synchronized and lock escalation
适用于高密度或高精度应用的高度可配置和可扩展的螺旋电容器设计
项目上线,旧数据需要修改,写SQL太麻烦,看Excel配合简单SQL的强大功能
【FPGA】状态机
Test Development
【FPGA】 SPI协议
pytest测试框架快速搭建
多线程04--线程的可见性
spark常见问题
Parasitic sensing common centroid binary weighted capacitor layout generation integrates layout, wiring, and cell capacitor size
Matching of MOS transistors with different layout styles
Monkey 介绍及使用
Airtest test framework construction
数据分析的步骤和常用方法