課程
/后端開發
/Java
/ThreadLocal
請問一下哈,自定義的ThreadLocal中,為什么不能直接聲明一個Map<Thread, T> 來保存value,而是要再套一個map?
2020-02-10
源自:ThreadLocal 4-1
正在回答
秋田君說的也很不錯, 我這里補充下, Map<Thread, T>這種結構,hash表沖突會很嚴重,舉個例子。map.put(thread1, 100);map.put(thread1, 200);map.put(thread1, 300);你發現沒有,一個map put了三個值,那取值的時候, 怎么辦呢?
同樣的 main 函數,使用老師的代碼執行會發現主線程不同 MyThreadLocal 實例中的數據是互不影響互不干擾的
public?static?void?main(String[]?args)?{ ????MyThreadLocal<Long>?userIdContext?=?new?MyThreadLocal<>()?{ ????????@Override ????????protected?Long?initialValue()?{ ????????????return?1L; ????????} ????}; ????MyThreadLocal<Connection>?connectionContext?=?new?MyThreadLocal<>(); ????System.out.println(userIdContext.get());?//?1 ????System.out.println(connectionContext.get());?//?null }
從使用上看應該是為了不同場景使用時數據隔離,同一線程之間不同 MyThreadLocal 實例間的數據隔離
@Deprecated public?class?MyThreadLocalWrong<T>?{ ????private?static?Map<Thread,?Object>?threadLocalMap?=?new?HashMap<>(); ????protected?T?initialValue()?{ ????????return?null; ????} ????public?synchronized?T?get()?{ ????????return?(T)?threadLocalMap.computeIfAbsent(Thread.currentThread(),?t?->?initialValue()); ????} ????public?synchronized?void?set(T?t)?{ ????????threadLocalMap.put(Thread.currentThread(),?t); ????} ????public?static?void?main(String[]?args)?{ ????????MyThreadLocalWrong<Long>?userIdContext?=?new?MyThreadLocalWrong<>()?{ ????????????@Override ????????????protected?Long?initialValue()?{ ????????????????return?1L; ????????????} ????????}; ????????MyThreadLocalWrong<Connection>?connectionContext?=?new?MyThreadLocalWrong<>(); ????????System.out.println(userIdContext.get());?//?1 ????????System.out.println(connectionContext.get());?//?1 ????} }
如果直接使用 Map<Thread, T> 來存儲數據,由于 threadLocalMap 是靜態變量,那么同一線程不同 MyThreadLocal 實例存儲時,數據會被覆蓋,讀取數據時,會得到錯亂的值!
應該為了解耦
舉報
設計者視角源碼級ThreadLocal分析教你建立線程安全感-你專屬的技術優越感
3 回答匿名內部類不能和泛型一起使用
2 回答為什么threadLocalMap要設計為Static的雙層map,如果設計為非靜態的單層map有什么問題?
3 回答使用ThreadLocal定義c的問題
1 回答為啥兩個Initial Value run ...在一起,1,13在一起?不是分開調用的嗎?啥原理呢
3 回答Integer為什么不是引用類型呢?
Copyright ? 2025 imooc.com All Rights Reserved | 京ICP備12003892號-11 京公網安備11010802030151號
購課補貼聯系客服咨詢優惠詳情
慕課網APP您的移動學習伙伴
掃描二維碼關注慕課網微信公眾號
2020-02-21
秋田君說的也很不錯, 我這里補充下, Map<Thread, T>這種結構,hash表沖突會很嚴重,舉個例子。map.put(thread1, 100);map.put(thread1, 200);map.put(thread1, 300);你發現沒有,一個map put了三個值,那取值的時候, 怎么辦呢?
2020-02-17
同樣的 main 函數,使用老師的代碼執行會發現主線程不同 MyThreadLocal 實例中的數據是互不影響互不干擾的
2020-02-17
從使用上看應該是為了不同場景使用時數據隔離,同一線程之間不同 MyThreadLocal 實例間的數據隔離
如果直接使用 Map<Thread, T> 來存儲數據,由于 threadLocalMap 是靜態變量,那么同一線程不同 MyThreadLocal 實例存儲時,數據會被覆蓋,讀取數據時,會得到錯亂的值!
2020-02-10
應該為了解耦