美文网首页
SimpleDateFormat--容易发生线程安全的类

SimpleDateFormat--容易发生线程安全的类

作者: MJLDG | 来源:发表于2019-10-30 20:55 被阅读0次

    在java中,可以使用 SimpleDateFormat 日期格式化类来对日期或者时间进行格式化,但在多线程环境下使用要注意线程安全问题。以下代码都是基于JDK1.8

     * <p>
     * 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.
    
    public class SimpleDateFormat extends DateFormat {
    

    源码文件中已经注明此类是线程不安全,使用过程中应当注意。
    并发问题主要发生在SimpleDateFormat 的format 方法, calendar.setTime(date);这一句。

     // Called from Format after creating a FieldDelegate
        private StringBuffer format(Date date, StringBuffer toAppendTo,
                                    FieldDelegate delegate) {
            // Convert input date to time field list
            calendar.setTime(date);
    
            boolean useDateFormatSymbols = useDateFormatSymbols();
    
    

    format方法中这个calendar是一个成员变量,如果A线程先设置了dateA值,执行到下一步,
    然后B线程又将这个calendar变量设置为dateB值,那么A线程后面获取到的calendar值将
    会是dateB值,而不是一开始设置的dateA值。要解决这个问题,可以使用ThreadLocal类解决并发问题。

    private static final ThreadLocal<DateFormat> ymdhmsFormat = ThreadLocal.withInitial(() ->
            new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
    );
    

    然后通过 ymdhmsFormat.get() 获取到对应的DateFormat 实例对象。其中ThreadLocal主要是通过
    一条线程对应一个DateFormat实例变量的方法来解决线程并发问题。即使多条线程同时访问format方法,
    但是因为每一条线程都对应一个DateFormat实例对象,所以能安全执行format方法,而不是发生时间错乱问题。

    相关文章

      网友评论

          本文标题:SimpleDateFormat--容易发生线程安全的类

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