[Java]解决SimpleDateFormat的parse和format不正确问题(并发/线程里使用的坑)

2021-06-03 1154点热度 0人点赞 0条评论

可能使用的时候没有注意,在做时间的解析和格式化的时候,写了一个全局的工具类或者把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.

原因我就不细究了,有兴趣的可以网上搜索,总之线程不安全就是了

解决办法

  1. 每次要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");
  2. 如果你还是介意每次使用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");

     

admin

这个人很懒,什么都没留下

文章评论

您需要 登录 之后才可以评论