天天看點

Java并發程式設計基礎-ThreadLocal的使用

章節目錄

  • ThreadLocal 簡介
  • ThreadLocal 使用

1.ThreadLocal 簡介

什麼是ThreadLocal

ThreadLocal 為線程變量,是一個以ThreadLocal對象為key,任意對象為值的存儲
結構,這個結構被附帶到線程上。
           

ThreadLocal的作用

通過set(T)來設定一個值,在目前線程下通過get()方法擷取到原先設定的值。
           

2.ThreadLocal 使用

  • 題目:設計一個方案統計每個接口的響應時間
  • 思路:
    • 采用AOP(面向切面程式設計),可以在方法調用前的切入點執行begin()方法,在方法調用後的切入點執行end()方法。
    • 每個請求本質上是線程執行的過程,那麼問題就變為統計每個線程執行過程的耗時。
      • 采用工具類+實力方式會産生過多工具類對象
      • 采用靜态方法方式,如果不同步共享變量會産生并發擷取系統時間的問題,統計不準确。
      • 采用同步方式統計接口響應時間,接口性能會下降。
    • 那麼有沒有一種方式是将不通接口響應時間值綁定到 不同線程上的方式,并且擷取方法一緻,但是時間值是每個線程特定可見的,答案就是使用ThreadLocal

Profiler

begin() 擷取接口執行時間點、end()擷取從begin()方法調用開始到end()方法被調用時的時間差,機關毫秒。

package org.seckill.Thread;

public class Profiler {


    private static final ThreadLocal<Long> TIME_THREADLOCAL = new ThreadLocal<Long>(){
        //第一次get()方法調用時會進行初始化,這個是在set()方法沒有被調用的情況下發生,每個線程調用一次
        protected Long initialValue() {
          return System.currentTimeMillis();
        }
    };

    //設定初始運作時刻
    public static final void begin(){
        TIME_THREADLOCAL.set(System.currentTimeMillis());
    }

    public static final long end(){
        return System.currentTimeMillis()- TIME_THREADLOCAL.get();
    }

    public static void main(String[] args) {
        Profiler.begin();
        Interrupted.SleepUnit.second(1);
        System.out.println("cost time "+Profiler.end());
    }
}

           

運作結果:

Java并發程式設計基礎-ThreadLocal的使用

運作結果