如何解决SimpleDateFormat线程不安全问题

2020-08-27  本文已影响0人  码而优则仕

借助ThreadLocal,解决线程安全问题:

package cn.com.yuns.deploy.utils;

import lombok.extern.slf4j.Slf4j;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @author wsq
 * @version DateUtil.java  2020/8/27  上午7:36 下午
 */
@Slf4j
public class DateUtil {
    private static Map<String, ThreadLocal<SimpleDateFormat>> sdfMap = new HashMap<>();


    public final static String MDHMSS = "MMddHHmmssSSS";
    public final static String YMDHMS = "yyyyMMddHHmmss";
    public final static String YMDHMS_ = "yyyy-MM-dd HH:mm:ss";
    public final static String YMD = "yyyyMMdd";
    public final static String YMD_ = "yyyy-MM-dd";
    public final static String HMS = "HHmmss";

    /**
     * 根据map中的key得到对应线程的sdf实例
     *
     * @param pattern map中的key
     * @return 该实例
     */
    private static SimpleDateFormat getSdf(final String pattern) {
        ThreadLocal<SimpleDateFormat> sdfThread = sdfMap.get(pattern);
        if (sdfThread == null) {
            //双重检验,防止sdfMap被多次put进去值,和双重锁单例原因是一样的
            synchronized (DateUtil.class) {
                sdfThread = sdfMap.get(pattern);
                if (sdfThread == null) {
                    log.debug("put new sdf of pattern " + pattern + " to map" + "\n");
                    sdfThread = new ThreadLocal<SimpleDateFormat>() {
                        @Override
                        protected SimpleDateFormat initialValue() {
                            log.debug("thread: " + Thread.currentThread() + " init pattern: " + pattern + "\n");
                            return new SimpleDateFormat(pattern);
                        }
                    };
                    sdfMap.put(pattern, sdfThread);
                }
            }
        }
        return sdfThread.get();
    }

    /**
     * 按照指定pattern解析日期
     *
     * @param date    要解析的date
     * @param pattern 指定格式
     * @return 解析后date实例
     */
    public static Date parseDate(String date, String pattern) {
        if (date == null) {
            throw new IllegalArgumentException("The date must not be null");
        }
        try {
            return getSdf(pattern).parse(date);
        } catch (ParseException e) {
            e.printStackTrace();
            log.error("解析的格式不支持:" + pattern);
        }
        return null;
    }

    /**
     * 按照指定pattern格式化日期
     *
     * @param date    要格式化的date
     * @param pattern 指定格式
     * @return 解析后格式
     */
    public static String formatDate(Date date, String pattern) {
        if (date == null) {
            throw new IllegalArgumentException("The date must not be null");
        } else {
            return getSdf(pattern).format(date);
        }
    }

    public static void main(String args[]) {
        new Thread(() -> log.error("日期:【{}】\n", DateUtil.formatDate(new Date(), MDHMSS))).start();
        new Thread(() -> log.error("日期:【{}】\n", DateUtil.formatDate(new Date(), YMDHMS_))).start();

    }
}

上一篇下一篇

猜你喜欢

热点阅读