ThreadLocal總結及主要方法的Java實現

1. ThreadLocal概述

1.ThreadLocal提供線程局部變量;開箱即用開銷小,可以代替多線程訪問共享變量時需要上鎖的需要。
在這裏插入圖片描述

在各種涉及的多線程語言都有,Java用哈希表表實現(ThreadLocalMap)

3.實現原理
在這裏插入圖片描述

2. 基本API

1.構造函數ThreadLocal()

2.初始化 initialValue()

只有線程在第一次調用get方法時,執行此方法。

3.訪問器 get/set

public T get(),返回ThreadLocal中當前線程副本的值。變量第一次get時沒有當前線程的值,就調用initilaVaule()的返回值。

4.回收 remove

以下手動來個demo(涉及到延遲加載)

//用泛型構造器賦初始值
public static ThreadLocal<Long> x = new ThreadLocal<>(){
        @Override
        protected Long initialValue() {
            System.out.println("Initial Value run...");
            return Thread.currentThread().getId(); //拿到當前線程ID
        }
    };
    public static void main(String[] argv){
         new Thread(){
           @Override
           public void run(){
               System.out.println(x.get());
           }
         }.start();
         System.out.println(x.get());
    }
}

結果是:(main函數中兩個不同get都各調用了一次InitialValue方法,每個線程都有自己的變量值)

下面是測試set方法:

public class APItests {
    public static ThreadLocal<Long> threadLocal = new ThreadLocal<Long>(){
        @Override
        protected Long initialValue() {
            System.out.println("Initial Value run...");
            return Thread.currentThread().getId();
        }
    };
    public static void main(String[] argv) {
        new Thread() {
            @Override
            public void run() {
                System.out.println(threadLocal.get());
            }
        }.start();
        threadLocal.set(6l);
        System.out.println(threadLocal.get());
    }
}

得到的結果如下:可見InitialValue只調用了一次
在這裏插入圖片描述

3. ThreadLocal使用場景

  • 1.線程安全

在這裏插入圖片描述

  • 2.線程資源一致
    基於線程池模型去Sychronized很危險:排隊去鎖消耗的時間導致CPU用不完
    eg:線程池中24個線程,打來100個併發量,一次只能24個,而用ThreadLocal收集數據很快且安全。
    同一個事務下的任務們必須保證原子性,也就是說下圖中的Task們都須通過同一個線程的getConnection()方法拿到完全相同的數據。首先判斷ThreadLocalMap中是否存在所需值,如果沒有就去連接池取,取到的值先存到線程共享的ThreadLocalMap中,再返回給對應Task。
    在這裏插入圖片描述

(3)併發計算
常見於分佈式計算,一臺機器多核並行
在這裏插入圖片描述

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