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

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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:

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

posted @   ~~Cc  阅读(1155)  评论(0编辑  收藏  举报
努力加载评论中...
点击右上角即可分享
微信分享提示