DateFormat的format()方法线程不安全的问题分析

Posted ~~Cc

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了DateFormat的format()方法线程不安全的问题分析相关的知识,希望对你有一定的参考价值。

最近看到《侦探剧场:堆内存神秘溢出事件》https://my.oschina.net/u/2368090/blog/1628720,于是自己也想测试了解一下DateFormat的多线程安全问题。

首先先看现象:做一个多线程使用同一个SimplyDateFormat的测试例子:

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

public class DateFormatTest {

    static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

    public static void main(String[] args) throws Exception{

        Date start = sdf.parse("2018-03-01");
        Date end = sdf.parse("2018-03-03");

        final Date other =sdf.parse("2018-03-07");
        for(int i=0; i<100; i++) {
            new Thread(new Runnable() {
                public void run() {
                    sdf.format(other);
                }
            }).start();
        }

        System.out.println("start:" + sdf.format(start));
        System.out.println("end:" + sdf.format(end));
    }

}

(这段代码在虚拟机能很快重现问题,在Mac上要迅速不断点击运行才会重现--)

预期结果:

技术分享图片 

出现线程安全的结果:

技术分享图片

现象看完之后找原因:

1.DateFormat(父类)定义了一个全局的Calendar:

技术分享图片

SimplyDateFormat的format()方法在线程不安全的情况下使用了全局的calendar:

技术分享图片

产生问题的大致运行顺序也许是这样的:

技术分享图片

以上是关于DateFormat的format()方法线程不安全的问题分析的主要内容,如果未能解决你的问题,请参考以下文章

DateFormat类中的format方法和parse方法

android.text.format.DateFormat 和 java.text.DateFormat 有啥区别

为啥 format.dateFormat 不能指定为字符串?

挑战练习9.5 日期格式化

d3 dateformat parse返回null

flinkdate_format返回啥类型