ThreadLocal使用及问题
为啥想到用ThreadLocal
JavaWeb的Http请求以及其他多线程情况下,经常会涉及到多线操作同一变量的问题,虽然有加锁以及同步等处理,但实现起来相对麻烦,而且不一定好用,所以想到了用ThreadLocal去处理。
代码
不对ThreadLocal原理做介绍,可以简单的理解为把一个数值绑定到了当前线程上,具体的可以百度。直接上代码:
public class Demo {
public static void main(String[] args){
Service service = new Service();
for(int i = 0; i < 200; i++){
final Integer num = i;
new Thread(new Runnable() {
@Override
public void run() {
service.setValue(num+1);
service.setNum(num+1);
try {
if(num % 2 == 0){
Thread.sleep(100);
} else{
Thread.sleep(300);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("value:" + service.getNum() + " threadLocalValue: "+service.getValue()+" " +"num: "+(num+1));
}
}).start();
}
}
}
class Service{
ThreadLocal<Integer> t = new ThreadLocal<>();
private Integer num = 0;
public void setNum(Integer num) {
this.num = num;
}
public Integer getNum(){
return this.num;
}
public void setValue(Integer value){
t.set(value);
}
public Integer getValue(){
return t.get();
}
}
运行结果
代码中创建了200个线程,通过判断当前循环的角标使偶数线程睡眠100ms,奇数的线程睡眠300ms,让结果更明显。
通过运行结果看出,num的值存在被线程覆盖,但ThreadLocal取出的值是正确的。
问题
如果使用线程池的话,运行多次后,会出现ThreadLocal并没有Set值但能get到值,这是因为线程池回收时,并没有清空ThreadLocal中的数据,可以手动remove()一下。