可能使用的时候没有注意,在做时间的解析和格式化的时候,写了一个全局的工具类或者把SimpleDateFormat的初始化,放在全局变量里面,导致在多线程或者高并发调用的时候,解析或者格式化出来的时间不正确或者直接报错的问题,刚开始查的时候,始终没看出来程序哪里的问题,简单的单元测试也正常,后来才发现是SimpleDateFormat线程不安全引起的!
JDK的文档如下:
Synchronization:
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.
原因我就不细究了,有兴趣的可以网上搜索,总之线程不安全就是了
解决办法
- 每次要parser或者format的时候,new一个对象,现在的机器性能都不会有什么问题的,每次使用,直接new就可以了
//每次使用new一个SimpleDateFormat对象 String string = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()); //parser也是 Date date = new SimpleDateFormat("yyyy-MM-dd").parse("2021-06-03");
- 如果你还是介意每次使用new一个对象会损耗性能,那么可以使用apache commons lang3的FastDateFormat:
如果是maven项目,引入:<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 --> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.12.0</version> </dependency>
如果是gradle项目,引入:
// https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 implementation group: 'org.apache.commons', name: 'commons-lang3', version: '3.12.0'
具体使用方法就比较简单了,基本上和SimpleDateFormat一样的:
//FastDateFormat对象可以放在全局,供多线程调用的! public static FastDateFormat sdf = FastDateFormat.getInstance("yyyy-MM-dd HH:mm:ss"); //其他地方调用(基本上和SimpleDateFormat一样的使用方法): String string = sdf.format(new Date()); Date date = sdf.parse("2021-06-03 09:37:00");
文章评论