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:

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

原文地址:https://www.cnblogs.com/cici20166/p/8525563.html