ThreadLocal應用及理解
阿新 • • 發佈:2020-09-11
轉載請註明出處:
1. 先展示threadLocal的一個簡單封裝,該封裝用來在不同的請求執行緒中解析使用者引數。在請求經過過濾器時,
對使用者的資訊進行設定入ThreadLocalContext 中,可在同一個請求的不同業務中獲取使用者的資訊引數。
import com.homepage.UserInfo; public class ThreadLocalContext { private static ThreadLocal<UserInfo> userThreadLocal = new ThreadLocal<>(); public staticUserInfo getThreadLocalContext(){ UserInfo user = userThreadLocal.get(); if (user == null){ return new UserInfo(); } return user; } public static void setUserThreadLocal(UserInfo user){ userThreadLocal.set(user); } public staticvoid clear(){ userThreadLocal.remove(); } }
以上為ThreadLocal的一個簡單封裝。
2. 使用的場景主要為:
- 每個執行緒需要有自己單獨的例項
- 例項需要在多個方法中共享,但不希望被多執行緒共享
3.原理:
每個執行的執行緒都會有一個型別為ThreadLocal.ThreadLocalMap的map,這個map就是用來儲存與這個執行緒繫結的變數,
map的key就是ThreadLocal物件,value就是執行緒正在執行的任務中的某個變數的包裝類Entry。可以通過set方法來看threadLocal實現的原理:
/** * Sets the current thread's copy of this thread-local variable * to the specified value. Most subclasses will have no need to * override this method, relying solely on the {@link #initialValue} * method to set the values of thread-locals. * * @param value the value to be stored in the current thread's copy of * this thread-local. */ public void set(T value) { Thread t = Thread.currentThread(); ThreadLocalMap map = getMap(t); if (map != null) map.set(this, value); else createMap(t, value); }
4.ThreadLocal作用:
在多執行緒程式中,同一個執行緒在某個時間段只能處理一個任務.我們希望在這個時間段內,任務的某些變數能夠和處理它的執行緒進行繫結,
在任務需要使用這個變數的時候,這個變數能夠方便的從執行緒中取出來.ThreadLocal能很好的滿足這個需求,用ThreadLocal變數的程式看起來
也會簡潔很多,因為減少了變數在程式中的傳遞。
5. 為什麼ThreadLocalMap的Entry是一個weakReference? 使用weakReference,能夠在ThreadLocal失去強引用的時候,ThreadLocal對應的Entry能夠在下次gc時被回收,回收後的空間能夠得到複用, 在一定程度下能夠避免記憶體洩露. 6. 使用ThreadLocal應該注意什麼? 在使用ThreadLocal物件,儘量使用static,不然會使執行緒的ThreadLocalMap產生太多Entry,從而造成記憶體洩露