ThreadLocal的轻纱拂去,到底是个什么鬼?
你,你,还有你用过threadLocal吗?答案显而易见。但是却被常常提起的一个东西。
如下是API种的解释:
该类提供了线程局部 (thread-local) 变量。这些变量不同于它们的普通对应物,因为访问某个变量(通过其 get 或 set 方法)的每个线程都有自己的局部变量,它独立于变量的初始化副本。ThreadLocal 实例通常是类中的 private static 字段,它们希望将状态与某一个线程(例如,用户 ID 或事务 ID)相关联。
嗯,ThreadLocal即是线程的局部变量副本,每个线程持有自己的副本。随着线程的生命周期结束,自动销毁。
package test.com;
public class TestImpl implements Test{
@Override
public void init(Integer i) {
// TODO Auto-generated method stub
ThreadLocal<Integer> tl = Main3.local;
Integer init = tl.get();
//未被初始化的话,初始化一个线程变量
if(init==null) {
System.out.println("initing…");
tl.set(i);
}
}
@Override
public void execute() {
// TODO Auto-generated method stub
System.out.println(Main3.local.get());
}
}
package test.com;
public class Main3 {
public static ThreadLocal<Integer> local = new ThreadLocal<>();
public static void main(String[] args) {
TestImpl impl = new TestImpl();
impl.execute();
impl.init(2);
impl.execute();
System.out.println("--------------------------");
TestImpl impl2 = new TestImpl();
impl2.execute();
impl2.init(5);
impl2.execute();
impl.execute();
System.out.println("-------------------------");
Thread t = new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
TestImpl impl3 = new TestImpl();
impl3.init(10);
impl3.execute();
}
});
t.start();
try {
t.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("-------------------------");
impl.execute();
impl2.execute();
}
}
//执行结果
null
initing…
2
--------------------------
2
2
2
-------------------------
initing…
10
-------------------------
2
2
分析:从程序的执行结果可以看出,threadLoacl只会在线程中生成变量副本,被该线程持有,
而和改线程中初始化多少个对象无关。
大家可能会说自己也可以缓存了什么的,但是有一点这个副本随着线程死亡而销毁。无需管理。