ThreadLocalはdemoを使用


public class ThreadLocalDemo {

    public static ThreadLocal threadName = new ThreadLocal(){
        protected String initialValue() {
            return "-1";
        }
    };

    public static void main(String[] args) throws InterruptedException {
        ThreadLocalDemo.threadName.set("789");
        Thread t1 = new Thread(){
            public void run() {
                ThreadLocalDemo.threadName.set("123");
                System.out.println("ThreadLocalDemo.threadName in t1 is : " + ThreadLocalDemo.threadName.get());
                ThreadLocalDemo.threadName.remove();
                System.out.println("ThreadLocalDemo.threadName in t1 is : " + ThreadLocalDemo.threadName.get());
            }
        };
        Thread t2 = new Thread(){
            public void run() {
                ThreadLocalDemo.threadName.set("456");
                System.out.println("ThreadLocalDemo.threadName in t2 is : " + ThreadLocalDemo.threadName.get());
                ThreadLocalDemo.threadName.remove();
                System.out.println("ThreadLocalDemo.threadName in t2 is : " + ThreadLocalDemo.threadName.get());
            }
        };
        t1.start();
        t1.join();
        t2.start();
        t2.join();
        System.out.println("ThreadLocalDemo.threadName in main is : " + ThreadLocalDemo.threadName.get());
    }
}
   ThreadLocal     demo,        :ThreadLocal    ,    remove           ,  ,       ,        ,        ,            。
public class ThreadLocalDemo4Executor {
    public static ThreadLocal threadName = new ThreadLocal(){
        protected String initialValue() {
            return "-1";
        }
    };

    public static void main(String[] args) throws InterruptedException {

        ExecutorService executor = Executors.newFixedThreadPool(10);
        ThreadLocalDemo.threadName.set("789");

        for(int i = 0; i < 20; i++) {
            executor.execute(new Thread(){
                public void run() {
                    System.out.println("Before####ThreadLocalDemo.threadName in thread:" + Thread.currentThread() + " is : " + ThreadLocalDemo.threadName.get());
                    ThreadLocalDemo.threadName.set(new Random().nextInt(100) + "");
                    System.out.println("After####ThreadLocalDemo.threadName in thread:" + Thread.currentThread() + " is : " + ThreadLocalDemo.threadName.get());
                }
            } );
        }
        System.out.println("ThreadLocalDemo.threadName in main is : " + ThreadLocalDemo.threadName.get());
    }
}

出力:
"C:\Program Files\Java\jdk1.8.0_60\bin\java""-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2017.2.3\lib\idea_rt.jar=55943:C:\Program Files\JetBrains\IntelliJ IDEA 2017.2.3\bin"-Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_60\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_60\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_60\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_60\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_60\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_60\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_60\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_60\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_60\jre\lib\extashorn.jar;C:\Program Files\Java\jdk1.8.0_60\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_60\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_60\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_60\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_60\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_60\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_60\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_60\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_60\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_60\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_60\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_60\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_60\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_60\jre\lib\rt.jar;C:\TestProj\billTest\target\classes;C:\EDISK\maven\repo\com\alibaba\fastjson\1.2.38\fastjson-1.2.38.jar"com.blackfish.bill.billlist.ThreadLocalDemo4Executor Before####ThreadLocalDemo.threadName in thread:Thread[pool-1-thread-1,5,main] is : -1 Before####ThreadLocalDemo.threadName in thread:Thread[pool-1-thread-2,5,main] is : -1 Before####ThreadLocalDemo.threadName in thread:Thread[pool-1-thread-3,5,main] is : -1 ThreadLocalDemo.threadName in main is : 789 After####ThreadLocalDemo.threadName in thread:Thread[pool-1-thread-3,5,main] is : 22 After####ThreadLocalDemo.threadName in thread:Thread[pool-1-thread-2,5,main] is : 13 Before####ThreadLocalDemo.threadName in thread:Thread[pool-1-thread-5,5,main] is : -1 After####ThreadLocalDemo.threadName in thread:Thread[pool-1-thread-5,5,main] is : 1 Before####ThreadLocalDemo.threadName in thread:Thread[pool-1-thread-5,5,main] is : 1 After####ThreadLocalDemo.threadName in thread:Thread[pool-1-thread-5,5,main] is : 55 Before####ThreadLocalDemo.threadName in thread:Thread[pool-1-thread-4,5,main] is : -1 After####ThreadLocalDemo.threadName in thread:Thread[pool-1-thread-4,5,main] is : 82 Before####ThreadLocalDemo.threadName in thread:Thread[pool-1-thread-4,5,main] is : 82 After####ThreadLocalDemo.threadName in thread:Thread[pool-1-thread-4,5,main] is : 30 Before####ThreadLocalDemo.threadName in thread:Thread[pool-1-thread-4,5,main] is : 30 Before####ThreadLocalDemo.threadName in thread:Thread[pool-1-thread-7,5,main] is : -1 After####ThreadLocalDemo.threadName in thread:Thread[pool-1-thread-1,5,main] is : 20 After####ThreadLocalDemo.threadName in thread:Thread[pool-1-thread-7,5,main] is : 49 Before####ThreadLocalDemo.threadName in thread:Thread[pool-1-thread-7,5,main] is : 49 Before####ThreadLocalDemo.threadName in thread:Thread[pool-1-thread-1,5,main] is : 20 After####ThreadLocalDemo.threadName in thread:Thread[pool-1-thread-4,5,main] is : 79 Before####ThreadLocalDemo.threadName in thread:Thread[pool-1-thread-8,5,main] is : -1 Before####ThreadLocalDemo.threadName in thread:Thread[pool-1-thread-5,5,main] is : 55 Before####ThreadLocalDemo.threadName in thread:Thread[pool-1-thread-3,5,main] is : 22 After####ThreadLocalDemo.threadName in thread:Thread[pool-1-thread-3,5,main] is : 81 Before####ThreadLocalDemo.threadName in thread:Thread[pool-1-thread-3,5,main] is : 81 Before####ThreadLocalDemo.threadName in thread:Thread[pool-1-thread-2,5,main] is : 13 Before####ThreadLocalDemo.threadName in thread:Thread[pool-1-thread-6,5,main] is : -1 Before####ThreadLocalDemo.threadName in thread:Thread[pool-1-thread-10,5,main] is : -1 After####ThreadLocalDemo.threadName in thread:Thread[pool-1-thread-2,5,main] is : 45 After####ThreadLocalDemo.threadName in thread:Thread[pool-1-thread-3,5,main] is : 71 Before####ThreadLocalDemo.threadName in thread:Thread[pool-1-thread-9,5,main] is : -1 After####ThreadLocalDemo.threadName in thread:Thread[pool-1-thread-5,5,main] is : 12 After####ThreadLocalDemo.threadName in thread:Thread[pool-1-thread-8,5,main] is : 54 Before####ThreadLocalDemo.threadName in thread:Thread[pool-1-thread-4,5,main] is : 79 After####ThreadLocalDemo.threadName in thread:Thread[pool-1-thread-1,5,main] is : 67 After####ThreadLocalDemo.threadName in thread:Thread[pool-1-thread-7,5,main] is : 56 After####ThreadLocalDemo.threadName in thread:Thread[pool-1-thread-4,5,main] is : 51 After####ThreadLocalDemo.threadName in thread:Thread[pool-1-thread-9,5,main] is : 44 After####ThreadLocalDemo.threadName in thread:Thread[pool-1-thread-10,5,main] is : 70 After####ThreadLocalDemo.threadName in thread:Thread[pool-1-thread-6,5,main] is : 94
修復:行ThreadLocalDemo.threadName.remove()を追加します.
 
public class ThreadLocalDemo4Executor {
    public static ThreadLocal threadName = new ThreadLocal(){
        protected String initialValue() {
            return "-1";
        }
    };

    public static void main(String[] args) throws InterruptedException {

        ExecutorService executor = Executors.newFixedThreadPool(10);
        ThreadLocalDemo.threadName.set("789");

        for(int i = 0; i < 20; i++) {
            executor.execute(new Thread(){
                public void run() {
                    System.out.println("Before####ThreadLocalDemo.threadName in thread:" + Thread.currentThread() + " is : " + ThreadLocalDemo.threadName.get());
                    ThreadLocalDemo.threadName.set(new Random().nextInt(100) + "");
                    System.out.println("After####ThreadLocalDemo.threadName in thread:" + Thread.currentThread() + " is : " + ThreadLocalDemo.threadName.get());
                    ThreadLocalDemo.threadName.remove();
                }
            } );
        }
        System.out.println("ThreadLocalDemo.threadName in main is : " + ThreadLocalDemo.threadName.get());
    }
}

出力:
ThreadLocalDemo.threadName in main is : 789 Before####ThreadLocalDemo.threadName in thread:Thread[pool-1-thread-1,5,main] is : -1 After####ThreadLocalDemo.threadName in thread:Thread[pool-1-thread-1,5,main] is : 23 Before####ThreadLocalDemo.threadName in thread:Thread[pool-1-thread-1,5,main] is : -1 Before####ThreadLocalDemo.threadName in thread:Thread[pool-1-thread-2,5,main] is : -1 After####ThreadLocalDemo.threadName in thread:Thread[pool-1-thread-2,5,main] is : 31 Before####ThreadLocalDemo.threadName in thread:Thread[pool-1-thread-2,5,main] is : -1 After####ThreadLocalDemo.threadName in thread:Thread[pool-1-thread-2,5,main] is : 93 Before####ThreadLocalDemo.threadName in thread:Thread[pool-1-thread-2,5,main] is : -1 After####ThreadLocalDemo.threadName in thread:Thread[pool-1-thread-2,5,main] is : 88 Before####ThreadLocalDemo.threadName in thread:Thread[pool-1-thread-2,5,main] is : -1 After####ThreadLocalDemo.threadName in thread:Thread[pool-1-thread-2,5,main] is : 62 Before####ThreadLocalDemo.threadName in thread:Thread[pool-1-thread-2,5,main] is : -1 After####ThreadLocalDemo.threadName in thread:Thread[pool-1-thread-2,5,main] is : 53 Before####ThreadLocalDemo.threadName in thread:Thread[pool-1-thread-2,5,main] is : -1 After####ThreadLocalDemo.threadName in thread:Thread[pool-1-thread-2,5,main] is : 3 Before####ThreadLocalDemo.threadName in thread:Thread[pool-1-thread-2,5,main] is : -1 After####ThreadLocalDemo.threadName in thread:Thread[pool-1-thread-2,5,main] is : 78 Before####ThreadLocalDemo.threadName in thread:Thread[pool-1-thread-2,5,main] is : -1 After####ThreadLocalDemo.threadName in thread:Thread[pool-1-thread-2,5,main] is : 48 Before####ThreadLocalDemo.threadName in thread:Thread[pool-1-thread-3,5,main] is : -1 After####ThreadLocalDemo.threadName in thread:Thread[pool-1-thread-3,5,main] is : 82 Before####ThreadLocalDemo.threadName in thread:Thread[pool-1-thread-3,5,main] is : -1 After####ThreadLocalDemo.threadName in thread:Thread[pool-1-thread-3,5,main] is : 21 Before####ThreadLocalDemo.threadName in thread:Thread[pool-1-thread-4,5,main] is : -1 After####ThreadLocalDemo.threadName in thread:Thread[pool-1-thread-4,5,main] is : 91 Before####ThreadLocalDemo.threadName in thread:Thread[pool-1-thread-2,5,main] is : -1 After####ThreadLocalDemo.threadName in thread:Thread[pool-1-thread-2,5,main] is : 8 Before####ThreadLocalDemo.threadName in thread:Thread[pool-1-thread-5,5,main] is : -1 After####ThreadLocalDemo.threadName in thread:Thread[pool-1-thread-5,5,main] is : 43 Before####ThreadLocalDemo.threadName in thread:Thread[pool-1-thread-6,5,main] is : -1 Before####ThreadLocalDemo.threadName in thread:Thread[pool-1-thread-7,5,main] is : -1 After####ThreadLocalDemo.threadName in thread:Thread[pool-1-thread-7,5,main] is : 87 After####ThreadLocalDemo.threadName in thread:Thread[pool-1-thread-6,5,main] is : 62 Before####ThreadLocalDemo.threadName in thread:Thread[pool-1-thread-8,5,main] is : -1 After####ThreadLocalDemo.threadName in thread:Thread[pool-1-thread-8,5,main] is : 56 Before####ThreadLocalDemo.threadName in thread:Thread[pool-1-thread-9,5,main] is : -1 After####ThreadLocalDemo.threadName in thread:Thread[pool-1-thread-9,5,main] is : 76 After####ThreadLocalDemo.threadName in thread:Thread[pool-1-thread-1,5,main] is : 74 Before####ThreadLocalDemo.threadName in thread:Thread[pool-1-thread-10,5,main] is : -1 After####ThreadLocalDemo.threadName in thread:Thread[pool-1-thread-10,5,main] is : 47
最も一般的なThreadLocalでは、データベース接続やSpringのSession管理などを解決するためにシーンが使用されます.フレームワークではマルチスレッドメカニズム、すなわちスレッド多重が一般的に使用されるため、入る制御ロジックのコードごとに新しい値がセットされ、終了時にremoveが必要になります.
例:
private static ThreadLocal connectionHolder
        = new ThreadLocal() {
    public Connection initialValue() {
        return DriverManager.getConnection(DB_URL);
    }
};

public static Connection getConnection() {
    return connectionHolder.get();
}

または、
public static Session getSession() throws InfrastructureException {
    Session s = (Session) threadSession.get();
    try {
        if (s == null) {
            s = getSessionFactory().openSession();
            threadSession.set(s);
        }
    } catch (HibernateException ex) {
        throw new InfrastructureException(ex);
    }
    return s;
}