日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java中ThreadLocal的使用

發布時間:2024/2/28 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java中ThreadLocal的使用 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

    • 在Map中存儲用戶數據
    • 在ThreadLocal中存儲用戶數據

java中ThreadLocal的使用

ThreadLocal主要用來為當前線程存儲數據,這個數據只有當前線程可以訪問。

在定義ThreadLocal的時候,我們可以同時定義存儲在ThreadLocal中的特定類型的對象。

ThreadLocal<Integer> threadLocalValue = new ThreadLocal<>();

上面我們定義了一個存儲Integer的ThreadLocal對象。

要存儲和獲取ThreadLocal中的對象也非常簡單,使用get()和set()即可:

threadLocalValue.set(1); Integer result = threadLocalValue.get();

我可以將ThreadLocal看成是一個map,而當前的線程就是map中的key。

除了new一個ThreadLocal對象,我們還可以通過:

public static <S> ThreadLocal<S> withInitial(Supplier<? extends S> supplier) {return new SuppliedThreadLocal<>(supplier);}

ThreadLocal提供的靜態方法withInitial來初始化一個ThreadLocal。

ThreadLocal<Integer> threadLocal = ThreadLocal.withInitial(() -> 1);

withInitial需要一個Supplier對象,通過調用Supplier的get()方法獲取到初始值。

要想刪除ThreadLocal中的存儲數據,可以調用:

threadLocal.remove();

下面我通過兩個例子的對比,來看一下使用ThreadLocal的好處。

在實際的應用中,我們通常會需要為不同的用戶請求存儲不同的用戶信息,一般來說我們需要構建一個全局的Map,來根據不同的用戶ID,來存儲不同的用戶信息,方便在后面獲取。

在Map中存儲用戶數據

我們先看下如果使用全局的Map該怎么用:

public class SharedMapWithUserContext implements Runnable {public static Map<Integer, Context> userContextPerUserId= new ConcurrentHashMap<>();private Integer userId;private UserRepository userRepository = new UserRepository();public SharedMapWithUserContext(int i) {this.userId=i;}@Overridepublic void run() {String userName = userRepository.getUserNameForUserId(userId);userContextPerUserId.put(userId, new Context(userName));} }

這里我們定義了一個static的Map來存取用戶信息。

再看一下怎么使用:

@Testpublic void testWithMap(){SharedMapWithUserContext firstUser = new SharedMapWithUserContext(1);SharedMapWithUserContext secondUser = new SharedMapWithUserContext(2);new Thread(firstUser).start();new Thread(secondUser).start();assertEquals(SharedMapWithUserContext.userContextPerUserId.size(), 2);}

在ThreadLocal中存儲用戶數據

如果我們要在ThreadLocal中使用可以這樣:

public class ThreadLocalWithUserContext implements Runnable {private static ThreadLocal<Context> userContext= new ThreadLocal<>();private Integer userId;private UserRepository userRepository = new UserRepository();public ThreadLocalWithUserContext(int i) {this.userId=i;}@Overridepublic void run() {String userName = userRepository.getUserNameForUserId(userId);userContext.set(new Context(userName));System.out.println("thread context for given userId: "+ userId + " is: " + userContext.get());}}

測試代碼如下:

public class ThreadLocalWithUserContextTest {@Testpublic void testWithThreadLocal(){ThreadLocalWithUserContext firstUser= new ThreadLocalWithUserContext(1);ThreadLocalWithUserContext secondUser= new ThreadLocalWithUserContext(2);new Thread(firstUser).start();new Thread(secondUser).start();} }

運行之后,我們可以得到下面的結果:

thread context for given userId: 1 is: com.flydean.Context@411734d4 thread context for given userId: 2 is: com.flydean.Context@1e9b6cc

不同的用戶信息被存儲在不同的線程環境中。

注意,我們使用ThreadLocal的時候,一定是我們可以自由的控制所創建的線程。如果在ExecutorService環境下,就最好不要使用ThreadLocal,因為在ExecutorService中,線程是不可控的。

本文的例子可以參考https://github.com/ddean2009/learn-java-concurrency/tree/master/ThreadLocal

更多精彩內容且看:

  • 區塊鏈從入門到放棄系列教程-涵蓋密碼學,超級賬本,以太坊,Libra,比特幣等持續更新
  • Spring Boot 2.X系列教程:七天從無到有掌握Spring Boot-持續更新
  • Spring 5.X系列教程:滿足你對Spring5的一切想象-持續更新
  • java程序員從小工到專家成神之路(2020版)-持續更新中,附詳細文章教程

更多教程請參考 flydean的博客

總結

以上是生活随笔為你收集整理的java中ThreadLocal的使用的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。