章節目錄
- 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());
}
}
運作結果:
運作結果