ThreadLocal 变量和 与线程池配合使用时可能会出现的问题
ThreadLocal 變量和 與線程池配合使用時(shí)可能會(huì)出現(xiàn)的問(wèn)題
ThreadLocal 的介紹和使用
先看下ThreadLocal變量的使用
public void set(T value) {Thread t = Thread.currentThread();ThreadLocalMap map = getMap(t);if (map != null)map.set(this, value);elsecreateMap(t, value);} //獲取Thread類(lèi)里面的 ThreadLocalMap 變量ThreadLocalMap getMap(Thread t) {return t.threadLocals;}public T get() {Thread t = Thread.currentThread();ThreadLocalMap map = getMap(t);if (map != null) {ThreadLocalMap.Entry e = map.getEntry(this);if (e != null) {@SuppressWarnings("unchecked")T result = (T)e.value;return result;}}return setInitialValue();}可以看出來(lái),ThreadLocal就是在每個(gè)線程 Thread 類(lèi)里的變量 ThreadLocalMap。
而ThreadLocalMap 這個(gè)Map和HashMap類(lèi)似。
從這可以看出來(lái),ThreadLocal 中有一個(gè)在每個(gè)線程中不一樣的Map(因?yàn)槭荰hread類(lèi)的成員變量),所以實(shí)現(xiàn)了一個(gè)多個(gè)線程隔離的數(shù)據(jù)集。
線程池的回顧
線程池的實(shí)現(xiàn)中,啟動(dòng)的工作線程如果有工作會(huì)一直工作,直到workQueue中的數(shù)據(jù)沒(méi)有,并且超過(guò)了pollingTime才會(huì)銷(xiāo)毀這個(gè)工作線程。
兩者結(jié)合的問(wèn)題
所以在使用線程池的時(shí)候再使用 ThreadLocal 變量就會(huì)有一個(gè),同一個(gè)工作線程執(zhí)行不同的任務(wù)時(shí),ThreadLocal變量就會(huì)有臟讀的現(xiàn)象。來(lái)看一個(gè)例子:
public static void main(String[] args) {ExecutorService executorService = Executors.newFixedThreadPool(2);final ThreadLocal<String> threadLocal = new ThreadLocal<String>();Runnable runnable = new Runnable() {public void run() {System.out.println(threadLocal.get() == null);threadLocal.set(Thread.currentThread().getName()+": name");}};executorService.submit(runnable);executorService.submit(runnable);executorService.submit(runnable);executorService.submit(runnable);executorService.submit(runnable);executorService.submit(runnable);executorService.shutdown();}console中打印的數(shù)據(jù):
true true false false false false結(jié)論
由上面的console中打印的數(shù)據(jù)可以看出來(lái),在提交后面幾個(gè)任務(wù)的時(shí)候 threadLocal都不是空值了。即說(shuō)明
線程池中多個(gè)任務(wù)可能會(huì)使用同一個(gè) ThreadLocal,原因是線程池可能會(huì)使用公用的線程來(lái)執(zhí)行任務(wù)
總結(jié)
以上是生活随笔為你收集整理的ThreadLocal 变量和 与线程池配合使用时可能会出现的问题的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: JAVA垃圾回收的几点知识
- 下一篇: Base64 加密算法原理