ThreadLocal & InheritableThreadLocal 使用的一些坑
阿新 • • 發佈:2018-11-29
- ThreadLocal在與執行緒池結合使用時可能會出現資料複用
執行緒池把執行緒提交到佇列,當被呼叫的時候如果存在空閒執行緒就回直接複用執行緒,僅僅是呼叫了使用者提交執行緒的run方法。所以當ThreadLocal引數使用完,記得呼叫remove方法。
public class B { static final ThreadLocal<String> threadParam = new ThreadLocal<>(); public static void main(String[] args) throws InterruptedException { //固定池內只有存活3個執行緒 ExecutorService execService = Executors.newFixedThreadPool(3); //死迴圈幾次才能看出效果 while (true) { Thread t = new Thread(()->{ threadParam.set("abc"); System.out.println("t1:" + threadParam.get()); //如果不呼叫remove,將引發問題 // threadParam.remove(); }); execService.execute(t); TimeUnit.SECONDS.sleep(1); Thread t2 = new Thread(()-> { System.out.println("t2:" + threadParam.get()); }); execService.execute(t2); } } }
- InheritableThreadLocal 和 執行緒池結合使用時會出現共享父執行緒的InhertiableThreadLocal
public static void main(String[] args) throws InterruptedException { //固定池內只有存活3個執行緒 ExecutorService execService = Executors.newFixedThreadPool(3); //死迴圈幾次才能看出效果 while (true) { //執行緒1,裡面有兩個子執行緒 Thread t = new Thread(()->{ threadParam.set("abc"); System.out.println("t1:" + threadParam.get()); Thread t2 = new Thread(()->{ System.out.println("t2:" + threadParam.get()); // threadParam.remove(); }); execService.execute(t2); Thread t3 = new Thread(()->{ System.out.println("t3:" + threadParam.get()); // threadParam.remove(); }); execService.execute(t3); Thread t4 = new Thread(()->{ System.out.println("t4:" + threadParam.get()); // threadParam.remove(); }); execService.execute(t4); }); execService.execute(t); TimeUnit.SECONDS.sleep(1); //執行緒4,執行緒1同級 Thread t5 = new Thread(()-> { threadParam.set("CBA"); System.out.println("t5:" + threadParam.get()); }); execService.execute(t5); } }
Another case see the below link:
https://blog.csdn.net/Sunfj0821/article/details/81349775