ThreadLocal的两种用法
生活随笔
收集整理的這篇文章主要介紹了
ThreadLocal的两种用法
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
?
典型場景一:
每個線程需要一個獨享的對象(通常是工具類,典型的類有 SimpleDateFormat 和 Random)
代碼示例:
public class ThreadLocalNormalUsage05 {public static ExecutorService threadPool = Executors.newFixedThreadPool(10);public static void main(String[] args) {for (int i = 0; i < 1000; i++) {int finalI = i;threadPool.submit(new Runnable() {@Overridepublic void run() {String date = new ThreadLocalNormalUsage05().date(finalI);System.out.println(date);}});}}public String date(int secods) {Date date = new Date(1000 * secods);SimpleDateFormat dateFormat = ThreadSafeFormatter.dateFormatThreadLocal.get();return dateFormat.format(date);} }class ThreadSafeFormatter {public static ThreadLocal<SimpleDateFormat> dateFormatThreadLocal = new ThreadLocal<SimpleDateFormat>(){@Overrideprotected SimpleDateFormat initialValue() {return new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");}}; }典型場景二:
每個線程內需要保存全局變量(例如在連接器中獲取用戶信息),可以讓不同方法直接使用,避免參數傳遞的麻煩。
這些信息在同一個線程內相同,但是在不同的線程內是不同的,所以不能使用 static 方法來解決。使用 ConcurrentHashMap,synchronized 等會對性能有影響。
代碼示例:
public class ThreadLocalNormalUsage06 {public static void main(String[] args) {new Service1().process();} }class Service1 {public void process() {User user = new User("小張");UserContextHolder.holder.set(user);new Service2().process();} }class Service2 {public void process() {User user = UserContextHolder.holder.get();System.out.println("service2" + user.name);new Service3().process();} }class Service3 {public void process() {User user = UserContextHolder.holder.get();System.out.println("service3" + user.name);UserContextHolder.holder.remove();} }class UserContextHolder {public static ThreadLocal<User> holder = new ThreadLocal<>(); }class User {String name;public User(String name) {this.name = name;} }總結
ThreadLocal 有 set 和 initialValue 兩種方法保存對象,當我們能夠控制對象初始化時機的時候可以用 initialValue。當我們控制不了,需要某些條件觸發的時候可用 set。
使用 ThreadLocal 的四點好處:
- 線程安全
- 不需要加鎖,提高執行效率
- 高效使用內存(對象生成),節省開銷。
- 免去傳參的麻煩,如場景二。
每一個線程都有一個 ThreadLocalMap,這里面存放的是 ThreadLocal,如果在使用線程池的環境下,不停的向 ThreadLocalMap 中新增 ThreadLocal,那么極有可能引發內存泄露,所以在最后調用完的時候需要記得刪除ThreadLocal。如 Service3 中的示例。
?
總結
以上是生活随笔為你收集整理的ThreadLocal的两种用法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 线程池状态和使用注意点
- 下一篇: 进化之路:故事从两个线程说起