还在用SimpleDateFormat格式化时间?小心经理锤你

场景

本来开开心心的周末时光,线上突然就疯狂报错,以为程序炸了,截停日志,发现是就是类似下述一段错误

java.lang.NumberFormatException: For input string: ".202006E.202006E44"at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:2043)at sun.misc.FloatingDecimal.parseDouble(FloatingDecimal.java:110)at java.lang.Double.parseDouble(Double.java:538)at java.text.DigitList.getDouble(DigitList.java:169)at java.text.DecimalFormat.parse(DecimalFormat.java:2089)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.github.springtools.SimpleDateFormatTest.lambda$null$0(Xxxxxxx.java:2020)at java.lang.Thread.run(Thread.java:748)

定位到错误处,发现是一个时间格式化(SimpleDateFormat)的异常,一个时间格式化怎么会导致这种错误,还使得接口不能正常调用

测试

拉出来,使用模拟接口多线程的环境,单独进行测试…

package com.github.springtools;import java.text.ParseException;import java.text.SimpleDateFormat;import java.util.stream.IntStream;public class SimpleDateFormatTest {    public static final SimpleDateFormat FORMAT = new SimpleDateFormat("yyyy-MM-dd");    public static void main(String[] args) throws ParseException {        System.out.println(FORMAT.parse("2020-06-06"));        System.out.println("--------单个调用结束--------");        System.out.println("--------多线程调用开始--------");                IntStream.rangeClosed(0, 10)                .forEach(i -> new Thread(() -> {                    try {                        System.out.println(FORMAT.parse("2020-06-06"));                    } catch (ParseException e) {                        e.printStackTrace();                    }                }).start());    }}

输出

Sat Jun 06 00:00:00 CST 2020--------单个调用结束----------------多线程调用开始--------Sat Jun 06 00:00:00 CST 2020Sat Jun 06 00:00:00 CST 2020Exception in thread "Thread-7" Exception in thread "Thread-8" java.lang.NumberFormatException: For input string: ".202006E.202006E44"at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:2043)at sun.misc.FloatingDecimal.parseDouble(FloatingDecimal.java:110)at java.lang.Double.parseDouble(Double.java:538)

罪魁祸首浮出水面,就是SimpleDateFormat的锅

线程不安全,去找Java文档里的SimpleDateFormat: https://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html

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.日期格式不同步。建议为每个线程创建单独的格式实例。如果多个线程同时访问一种格式,则必须在外部进行同步。

解决方法

使用ThreadLocal

// ThreadLocalpublic static final ThreadLocal THREADLOCAL_FORMAT = ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy-MM-dd"));IntStream.rangeClosed(0, 5)        .forEach(i -> new Thread(() -> {            try {                System.out.println("ThreadLocal:" + THREADLOCAL_FORMAT.get().parse("2020-06-06"));            } catch (ParseException e) {                e.printStackTrace();            }        }).start());

使用Java 8中的时间处理

public static final DateTimeFormatter JAVA8_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");IntStream.rangeClosed(0, 5)        .forEach(i -> new Thread(() -> {            try {                System.out.println("JAVA8_FORMATTER:" + JAVA8_FORMATTER.parse("2020-06-06"));            } catch (ParseException e) {                e.printStackTrace();            }        }).start());

总结

使用多线程的时候,一定要考虑到其调用到的实例变量,Java8中时间格式化DateTimeFormatter是用final修饰的,不可变类,所以是线程安全的,或者在线程中调用ThreadLocal也是可以的

java 时间格式化_还在用SimpleDateFormat格式化时间?小心经理锤你相关推荐

  1. 日期格式化为yyyymmdd_你还在用SimpleDateFormat格式化时间嘛

    Jdk1.8之时间处理 该文章已经同步到Github:https://github.com/stackInk/makerstack 1. 传统时间处理的问题 1.1 多线程环境下的SimpleDate ...

  2. java 时间格式化_彻底解决Spring mvc中时间的转换和序列化等问题

    痛点 在使用Spring mvc 进行开发时我们经常遇到前端传来的某种格式的时间字符串无法用java8的新特性java.time包下的具体类型参数来直接接收. 我们使用含有java.time封装类型的 ...

  3. java手表怎么设置时间设置时间设置_佳明手表怎么设置时间?

    随着近期人们对健身的热衷,许多腕表厂商纷纷开发起了运动腕表,其中就有一个名为佳明的手表品牌开始为人们所了解,那么你知道佳明手表怎么设置时间吗?下面就由小编来为大家科普一下吧! 佳明手表怎么设置时间?想 ...

  4. python对浮点类型的数据进行格式化_全网最细 Python 格式化输出用法讲解(推荐)...

    免费资源网 - https://freexyz.cn/ 一.使用 print() 函数 在 Python 中,print() 函数支持格式化输出,与 C 语言的 printf 类似. 1. 格式化输出 ...

  5. 黑苹果双系统时间不一致_解决 Windows/macOS 双系统时间不同步问题

    概述 本文最后更新时间:2020年10月9日 安装了 Windows/macOS 双系统的同学,一定遇到过双系统时间不同步的问题.具体表现是,一旦进入过 macOS 系统,Windows 中的时间就会 ...

  6. java 友好时间显示_仿微信的IM聊天时间显示格式(含iOS/Android/Web实现)[图文+源码]...

    本文为原创分享,转载请注明出处. 1.引言 即时通讯IM应用中的聊天消息时间显示是个再常见不过的需求,现在都讲究用户体验,所以时间显示再也不能像传统软件一样简单粗地暴显示成"年/月/日 时: ...

  7. 字符串格式化成时间格式_小程序wxs中的时间格式化以及格式化时间和date时间互转...

    WXS(WeiXin Script)是小程序的一套脚本语言,wxs 与 javascript 是不同的语言,有自己的语法,并不和 javascript 一致.其中包括了很多日常使用的javascrip ...

  8. java spit 点_如何在PyGame中按时间点增加精灵的spit

    我正在Pygame制作一个游戏,其中一些角色出现在屏幕的一侧并移动到另一侧,在那里他们传送到他们开始的地方并再次进行 . 我希望精灵一次出现一个,它们的产生之间有一个随机的时间增量 . 我为精灵创建了 ...

  9. 华为手机如何调时间显示_华为手机照片如何出现时间地点天气,教你30秒,一学就会...

     阅读本文前,请您先点击上面的"蓝色字体",再点击"关注",这样您就可以继续免费收到文章了.每天都会有分享,都是免费订阅,请您放心关注.            ...

最新文章

  1. Linux下的redis的持久化,主从同步及哨兵
  2. 不得不知的小程序基本知识
  3. “女版乔布斯”被定罪!曾靠“一滴血”公司狂揽40亿,如今面临最高20年监禁...
  4. Infiniband网络抓包
  5. 【SICP练习】107 练习3.8
  6. Mac 技术篇-应用程序被锁定无法进行卸载问题解决方法,文件、文件夹被锁定无法移入废纸篓处理方法,卡巴斯基被锁定如何进行卸载演示
  7. 如何安装python3.7.6_CentOS7安装Python3.7.6,配置pip,安装配置virtualenv和virtualenvwrapper...
  8. AndroidStudio新建项目报错build failed
  9. Maven的核心概念
  10. 符号_液压图形符号识别之流量控制阀符号原理
  11. 3d效果图制作傻瓜软件_装修房子自己做3D效果图,哪些3D室内设计软件比较合适?...
  12. java excel 数组公式_Excel数组公式怎么使用? Excel数组公式计算的实例教程
  13. python计算2的n次方_python求n次方
  14. spyder4升级到spyder5出现缺少依赖库spyder_kernels问题解决
  15. CTE 递归查询全解
  16. Autodesk 2013 免费下载 及所有产品product Key(产品密匙)
  17. U盘里面空间占用了.但是却不显示任何东西
  18. 腾讯地图个性化图层创建及发布
  19. TokenInsight 对话首席——钱包安全与发展
  20. livy(0.5) on zeppelin(0.8)报No YARN application is found with tag问题解决

热门文章

  1. 大数据分析的处理流程
  2. C++算法学习(力扣:1122. 数组的相对排序)
  3. Danfo.js专题 - Danfo.js与Dnotebook简介与入门
  4. Android课程思维导图,Android实现思维导图
  5. java netty 面试_Java 200+ 面试题补充② Netty 模块
  6. 预算分配Budget Allocation:Morphl-AI的营销科学解决方案(一)
  7. 笔记︱决策树族——梯度提升树(GBDT)
  8. 用Lightroom Classic CC2019 mac合并照片以创建全景和HDR全景
  9. Ubuntu16.04再次装机记
  10. JQuery——实现Ajax应用