高并发下时间转换异常

本贴最后更新于 2158 天前,其中的信息可能已经时异事殊

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

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 方法。

  • B3log

    B3log 是一个开源组织,名字来源于“Bulletin Board Blog”缩写,目标是将独立博客与论坛结合,形成一种新的网络社区体验,详细请看 B3log 构思。目前 B3log 已经开源了多款产品:SymSoloVditor思源笔记

    1063 引用 • 3453 回帖 • 203 关注
  • Java

    Java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的。Java 技术具有卓越的通用性、高效性、平台移植性和安全性。

    3187 引用 • 8213 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...
chaigx
欢迎关注我的公众号:程序之声。有些文章没办法同步过来,访问个人博客:http://www.chaiguanxin.com 杭州