SimpleDateFormat in Java is not Thread-Safe, use Carefully.

java文档中说明了这个是一个非线程安全的类,建议为每个线程创建独立的日期格式。

Date formats are not synchronized.
It is recommended to create separate format instances for each thread.
If multiple threads access a format concurrently, it must be synchronized externally.

查看源码,它之所以是非线程安全的类是因为它使用共享的属性变量。

    protected Calendar calendar;
    

    private void initializeCalendar(Locale loc) {
        if (calendar == null) {
            assert loc != null;
            // The format object must be constructed using the symbols for this zone.
            // However, the calendar should use the current default TimeZone.
            // If this is not contained in the locale zone strings, then the zone
            // will be formatted using generic GMT+/-H:MM nomenclature.
            calendar = Calendar.getInstance(TimeZone.getDefault(), loc);
        }
    }

 

使用ThreadLocal变量去容纳DateFormat对象,可以解决线程非安全的问题。上代码:

package com.haleywang.demo;

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

public class DateFormatTest {

    private static final ThreadLocal<DateFormat> df = new ThreadLocal<DateFormat>() {
        @Override
        protected DateFormat initialValue() {
            return new SimpleDateFormat("yyyy-MM-dd");
        }
    };

    public Date convert(String source) throws ParseException {
        return df.get().parse(source);
    }
}