ThreadLocal 解決SimpleDateFormat非線程安全

大體意思:Tim Cull碰到一個SimpleDateFormat帶來的嚴重的性能問題,該問題主要有SimpleDateFormat引起,建立一個 SimpleDateFormat實例的開銷比較昂貴,解析字符串時間時頻繁建立生命週期短暫的實例致使性能低下。即便將 SimpleDateFormat定義爲靜態類變量,貌似能解決這個問題,可是SimpleDateFormat是非線程安全的,一樣存在問題,若是用 ‘synchronized’線程同步一樣面臨問題,同步致使性能降低(線程之間序列化的獲取SimpleDateFormat實例)。java

Tim Cull使用Threadlocal解決了此問題,對於每一個線程SimpleDateFormat不存在影響他們之間協做的狀態,爲每一個線程建立一個SimpleDateFormat變量的拷貝或者叫作副本,代碼以下:apache

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

/** 
 * 使用ThreadLocal以空間換時間解決SimpleDateFormat線程安全問題。 
 */
public class DateUtil {
    private static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
    @SuppressWarnings("rawtypes")
    private static ThreadLocal threadLocal = new ThreadLocal() {
        protected synchronized Object initialValue() {
            return new SimpleDateFormat(DATE_FORMAT);
        }
    };

    public static DateFormat getDateFormat() {
        return (DateFormat) threadLocal.get();
    }

    public static Date parse(String textDate) throws ParseException {
        return getDateFormat().parse(textDate);
    }
}

 

建立一個ThreadLocal類變量,這裏建立時用了一個匿名類,覆蓋了initialValue方法,主要做用是建立時初始化實例。也能夠採用下面方式建立;安全

import java.text.DateFormat;
import java.text.SimpleDateFormat;

/** 
 * 使用ThreadLocal以空間換時間解決SimpleDateFormat線程安全問題
 */
public class DateUtil {    
    private static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
    private static ThreadLocal threadLocal = new ThreadLocal();
    // 第一次調用get將返回null
    // 獲取線程的變量副本,若是不覆蓋initialValue,第一次get返回null,
    // 故須要初始化一個SimpleDateFormat,並set到threadLocal中
    public static DateFormat getDateFormat() {
        DateFormat df = (DateFormat) threadLocal.get();
        if (df == null) {
            df = new SimpleDateFormat(DATE_FORMAT);  
            threadLocal.set(df);
        }
        return df;
    }
}

咱們看下咱們覆蓋的initialValue方法:性能

protected T initialValue() {
    return null;    // 直接返回null
}

固然也可使用:spa

apache commons-lang包的DateFormatUtils或者FastDateFormat實現,apache保證是線程安全的,而且更高效。線程

相關文章
相關標籤/搜索