美文网首页
如何解决SimpleDateFormat线程不安全问题

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

作者: 码而优则仕 | 来源:发表于2020-08-27 20:58 被阅读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();
    
        }
    }
    
    

    相关文章

      网友评论

          本文标题:如何解决SimpleDateFormat线程不安全问题

          本文链接:https://www.haomeiwen.com/subject/pauhsktx.html