1. 程式人生 > >ThreadLocal類與SimpleDateFormat類

ThreadLocal類與SimpleDateFormat類

ThreadLocal類維持執行緒封閉性,可以使執行緒中的某個值與儲存值得物件關聯起來。為每個使用該變數的執行緒都存有一份獨立的指令碼,因此get總是返回當前執行執行緒在呼叫set時設定的最新值。

ThreadLocal物件通常用於防止對可變的單例項變數(Singleton)或全域性變數進行共享(在多執行緒應用程式在沒有協同的情況下使用全域性變數時,就不是執行緒安全的)

深入理解Java:SimpleDateFormat安全的時間格式化

SimpleDateFormat的執行緒安全問題與解決方案

SimpleDateFormat類的非執行緒安全:

public class MTAuth {

    private static final String HMAC_SHA1_ALGORITHM = "HmacSHA1";
    // SimpleDateFormat 這個是非執行緒安全的
    private static SimpleDateFormat df = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss z", Locale.ENGLISH);
    public static String getAuthDate(Date date) {

        df.setTimeZone(TimeZone.getTimeZone("GMT"));
        String dateString = df.format(date);

        return dateString;

    }
}

執行緒安全:

public class DwUtil {
    private static final Logger LOG = LoggerFactory.getLogger(DwUtil.class.getName());
    private static ThreadLocal<SimpleDateFormat> local1 = new ThreadLocal<SimpleDateFormat>();
    private static ThreadLocal<SimpleDateFormat> local2 = new ThreadLocal<SimpleDateFormat>();

    public static Date parseDate(String str, boolean lenient) {
        SimpleDateFormat sdf = local1.get();
        if (sdf == null) {
            sdf = new SimpleDateFormat("yyyy-MM-dd", Locale.US);
            local1.set(sdf);
        }

        try {
            sdf.setLenient(lenient);
            return sdf.parse(str);
        } catch (Exception e) {
            return null;
        }
    }

    public static String formatDate(Date date) {
        SimpleDateFormat sdf = local1.get();
        if (sdf == null) {
            sdf = new SimpleDateFormat("yyyy-MM-dd", Locale.US);
            local1.set(sdf);
        }

        return sdf.format(date);
    }
}