threadlocal變量和單個線程關聯,簡單來講,類似於(具體可參考jdk源碼):
Java代碼
public class FakeThreadLocal<T> {
private final Map<Thread, T> values = new HashMap<Thread, T>();
public T get() {
return values.get(Thread.currentThread());
}
public void set(T t) {
values.put(Thread.currentThread(), t);
}
}
應用場景1,創建壹個 SimpleDateFormat實例的開銷比較昂貴,解析字符串時間時頻繁創建生命周期短暫的實例導致性能低下。即使將 SimpleDateFormat定義為靜態類變量,貌似能解決這個問題,但是SimpleDateFormat是非線程安全的,同樣存在問題,如果用 ‘synchronized’線程同步同樣面臨問題,同步導致性能下降(線程之間序列化的獲取SimpleDateFormat實例)。
使用Threadlocal解決了此問題,對於每個線程SimpleDateFormat不存在影響他們之間協作的狀態,為每個線程創建壹個SimpleDateFormat變量的拷貝或者叫做副本。
Java代碼
public class Test
{
// SimpleDateFormat is not thread-safe, so give one to each thread
private static final ThreadLocal<SimpleDateFormat> formatter = new ThreadLocal<SimpleDateFormat>(){
@Override
protected SimpleDateFormat initialValue()
{
return new SimpleDateFormat("yyyyMMdd HHmm");
}
};
public String formatIt(Date date)
{
return formatter.get().format(date);
}
}
應用場景2,在servlet/filter中保存初始狀態,以便解決並發問題。
應用場景3,在壹些框架中保存和當前線程有關的上下文。