1. ThreadLocal简介
通过ThreadLocal创建的对象只允许当前线程去使用。 尽管对于同一个对象看起来会有多个线程去访问,但是彼此之间是互相不影响的。其本质是一个Key,Value键值对,其key就是线程。
2. 一个最简单的调用
public class DemoApplication {
// private static ThreadLocal<String> threadLocal = new ThreadLocal<>();//不设置默认值
private static ThreadLocal<String> threadLocal = new ThreadLocal<>(){//设置默认值
@Override
protected String initialValue(){
return "";
}
};
public static void main(String[] args) throws InterruptedException {
threadLocal.set("java-1");//如果不设置初始值,也没有重写initialValue,则为null
Thread.sleep(1000);
System.out.println(threadLocal.get());//java-1
}
}
3. 一个复杂的多线程使用
public class DemoApplication {
private static ThreadLocal<String> threadLocal = new ThreadLocal<>();//不设置默认值
private static Random random = new Random(System.currentTimeMillis());
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(()->{
threadLocal.set("Thread-1");
try{
Thread.sleep(random.nextInt(1000));
System.out.println(Thread.currentThread().getName()+" "+threadLocal.get());
}catch(InterruptedException e){
e.printStackTrace();
}
});
Thread t2 = new Thread(()->{
threadLocal.set("Thread-2");
try{
Thread.sleep(random.nextInt(1000));
System.out.println(Thread.currentThread().getName()+" "+threadLocal.get());
}catch(InterruptedException e){
e.printStackTrace();
}
});
t1.start();
t2.start();
t1.join();//等待t1 t2执行完毕
t2.join();
System.out.println("================");
System.out.println(Thread.currentThread().getName()+ " "+threadLocal.get());
}
}
上述代码,看起来3个线程(含主线程)对同一个对象进行了操作,但是3个线程里对于ThreadLocal的读、写都是互不影响的。 如果是普通的对象,那么3个线程就会互相影响干扰。