ThreadLocal 線程本地變量

簡介

官方文檔有道之後的結果。

該類提供線程本地變量。這些變量與一般的變量不同,每個線程訪問一個線程(通過get或set方法)有自己獨立的變量初始化副本。ThreadLocal實例通常是私有的靜態字段在類希望關聯狀態的線程(例如,一個用戶ID或交易ID)

個人理解:通過set() 方法將變量實例申明到一個和線程綁定的單獨空間,或者理解爲使用key-value形式存儲變量,線程爲key,set的變量實例爲value,使用get() 方法獲取時即用當前線程去取對應的value。這樣就會在各個線程之間互不干擾的使用同一個變量名的不同變量實例,存取也不用擔心線程問題。

情景假設

客戶端向服務器請求數據庫數據,每次請求都需要對數據庫進行操作,每一次的請求都通過new Thread的形式創建線程異步處理,這樣的話每一次請求都需要建立一個數據庫Connection,當然可以在每個線程創建Connection但是不方便進行封裝。

    // 創建線程局部變量 方便使用全局調用
    public static final ThreadLocal<Map<String, Connection>> LOCAL = new ThreadLocal<>();

    /**
     * 根據表名建立數據庫連接
     *
     * @author fengzhen
     * @version v1.0, 2017/9/4 10:40
     */
    public static Connection getConDb(String dbName) throws SQLException, ClassNotFoundException {
        Map<String, Connection> connectionMap = LOCAL.get();
        if (connectionMap == null){
            connectionMap = new HashMap<>();
            LOCAL.set(connectionMap);
        }
        Connection conn = connectionMap.get(dbName);
        if (conn == null || conn.isClosed()) {
            conn = DriverManager.getConnection(DBUtils.SQLSERVER_URL + dbName, DBUtils.USER, DBUtils.PASSWORD);
            connectionMap.put(dbName,conn);
        }
        return conn;
    }

如上,之後想要獲取Connection可以直接通過 LOCAL.get() 獲取當前線程建立的Connection,而不用考慮線程的問題。

常用方法

set()

將當前線程的本地變量的副本設置爲指定的值。
即相當於map的put方法,存入數據。

get()

返回當前線程的本地線程變量的值。
即,get方法,使用線程爲key取值。

remove()

爲該線程本地變量移除當前線程的值。
即,remove方法

initialValue()

返回該線程本地變量的當前線程的“初始值”。該方法將第一次調用一個線程訪問變量的get()方法,除非線程之前調用的set(T)的方法,在這種情況下,初值的方法不會被調用的線程。通常情況下,這種方法是每個線程調用一次,但它可能在後續調用remove()隨後get()再次調用。
這簡單執行返回null;如果程序員渴望線程局部變量有一個初始值非零,ThreadLocal必須子類,並重寫這個方法。通常,匿名內部類將被使用。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章