高并发下时间转换异常

  |   0 评论   |   0 浏览

最近测试在做压测的时候,发现一个接口偶尔会报错,对于有错必查的程序员来说,一定要看看是什么问题。查看日志发现这样的错误。

java.lang.NumberFormatException: For input string: ""
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Long.parseLong(Long.java:601)
at java.lang.Long.parseLong(Long.java:631)
at java.text.DigitList.getLong(DigitList.java:195)
at java.text.DecimalFormat.parse(DecimalFormat.java:2051)
at java.text.SimpleDateFormat.subParse(SimpleDateFormat.java:1869)
at java.text.SimpleDateFormat.parse(SimpleDateFormat.java:1514)
at java.text.DateFormat.parse(DateFormat.java:364)
at com.cimu.util.date.DateUtils.getDateFormat(DateUtils.java:107)
at com.cimu.util.date.DateUtils.getNowDate(DateUtils.java:167)

问题排查

查看代码,确实有一个地方调用了时间转换的方法,但是那个方法是项目中使用的工具类,使用了java.text包下的SimpleDateFormat来进行转换;代码如下:

public final static String DATE_PATTERN = "yyyy-MM-dd";
// 日期格式化
private static DateFormat dateFormat = null;
static {
  dateFormat = new SimpleDateFormat(DATE_PATTERN);
}
public static Date getNowDate() {
  return DateUtils.getDateFormat(dateFormat.format(new Date()));
}

public static Date getDateFormat(String date) {
    try {
        return dateFormat.parse(date);
  } catch (ParseException e) {
        log.error("转换报错",e);
  }
    return null;
}

在业务代码里,使用了getNowDate()方法。找到问题代码了,那是什么原因会报错呢?

问题分析

从报错日志看,应该是在Long类的第601行报错,
imagepng
发现这里就一行代码。就是抛出NumberFormatException异常。

在往上找,找到Long类的第631行,
imagepng
这里就是调用了Long类的parseLong方法。跟着错误日志接着往上找。

找到DigitList类
imagepng
看到这里,应该是temp.toString()传了一个空字符串,导致Long那边的方法报错。
应该是192行的for循环没有执行,查看count,decimalAt的属性,在高并发下会存在问题。
imagepng

问题解决

查到原因了,那么如何解决呢?

1、在getNowDate()方法前面加上synchronized
该方法会影响性能
2、SimpleDateFormat不使用全局静态变量,每次调用都生成一个,这样会增加开销。

3、使用commons.lang3下的DateUtils和DateFormatUtils方法。

也可以关注我的公众号,及时获取最新文章

关注公众号,回复:下载
获取百度下载神器:
imagepng

本文为博主原创文章,未经博主允许不得转载。