在activeJDBC框架内部的实现中看到了 ThreadLocal 这个类,记录下了每个线程独有的连接

private static final ThreadLocal<HashMap<String, Connection>> connectionsTL = new ThreadLocal<>();

感觉是个知识点,就打开源码看看了。先看一下源码里的解释

This class provides thread-local variables. These variables differ from their normal counterparts in that each thread that accesses one (via its get or set method) has its own, independently initialized copy of the variable. ThreadLocal instances are typically private static fields in classes that wish to associate state with a thread (e.g., a user ID or Transaction ID).

这个鸟文,瞎翻译一下,就是:

这个类提供了供线程专享的变量。这些变量不同与其它普通的变量,它是每个线程都有一个自己的独立初始化的变量(通过get和set方法实现)。这个类的实例常用于类的私有静态字段,以实现每个线程都有自己的状态(例如userId,事务ID等)。

先跑一下用法吧,

package com.test.threadlocal;  public class TestController {          private static int index = 0;     private static String str = "这个字符串是每个线程共享的";     // 这个变量,看似是一个类的静态属性,实则是每个线程有自己独有的区域     private static ThreadLocal<String> threadStr = new ThreadLocal<String>() {         @Override         protected String initialValue() {             return "main线程专享";         }     };                public static void main(String[] args) throws InterruptedException {         for(int i = 0; i < 3; i++) {             Thread t = new MyThread();             t.start();             t.join();         }                  System.out.println(str);         System.out.println(threadStr.get());     }          static class MyThread extends Thread{          @Override         public void run() {             index++;             str = "第" + index + "个str";             threadStr.set("第" + index + "个threadStr");         }                       }  } 

这个例子中,从str和threadStr变量的打印结果可以看出来。str被所有的线程读和写,threadStr在每个线程内部开辟了一块线程专享的区域。接下来,我们看一下具体实现。
先看一下构造函数

     /**      * ThreadLocals rely on per-thread linear-probe hash maps attached      * to each thread (Thread.threadLocals and      * inheritableThreadLocals).  The ThreadLocal objects act as keys,      * searched via threadLocalHashCode.  This is a custom hash code      * (useful only within ThreadLocalMaps) that eliminates collisions      * in the common case where consecutively constructed ThreadLocals      * are used by the same threads, while remaining well-behaved in      * less common cases.      */     private final int threadLocalHashCode = nextHashCode();      /**      * Creates a thread local variable.      * @see #withInitial(java.util.function.Supplier)      */     public ThreadLocal() {     }

构造函数是空的,但是,该类有一个私有整型常量threadLocalHashCodenextHashCode()方法我们就不看了,省的一如源码深似海。看鸟文的话,大概就是每new一个ThreadLocal变量的时候,就会生成一个散列码,该码非极端情况下与某个整数取模后不容易冲突(这句话有点迷吧,其实我也不懂)
然后看一下set方法