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个线程就会互相影响干扰。