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:
产生问题的大致运行顺序也许是这样的:
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步