Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >DateFormat 线程不安全

DateFormat 线程不安全

作者头像
囚兔
发布于 2018-02-08 02:51:17
发布于 2018-02-08 02:51:17
72300
代码可运行
举报
文章被收录于专栏:IT杂记IT杂记
运行总次数:0
代码可运行

一、测试

测试代码如下: 

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    public static void main(String[] args) throws ParseException{
        for (int i = 0; i < 2; i++) {
            Thread t = new Thread(new TestRunnable(), "t-" + i);
            t.start();
        }
    }

    static class TestRunnable implements Runnable {

        @Override
        public void run() {
            while(true) {

                long dateTime = 0;
                String dateStr = "2016-05-09 08:21:02";

                try{
                    Date dt = sdf.parse(dateStr);
                    dateTime = dt.getTime();
                } catch(Exception e){
                    e.printStackTrace();
                }

                if(dateTime < 0) {
                    System.out.println(dateTime);
                }
            }
        }
    }

输出结果:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
java.lang.NumberFormatException: For input string: ""
	at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
	at java.lang.Long.parseLong(Long.java:453)
	at java.lang.Long.parseLong(Long.java:483)
	at java.text.DigitList.getLong(DigitList.java:194)
	at java.text.DecimalFormat.parse(DecimalFormat.java:1316)
	at java.text.SimpleDateFormat.subParse(SimpleDateFormat.java:2088)
	at java.text.SimpleDateFormat.parse(SimpleDateFormat.java:1455)
	at java.text.DateFormat.parse(DateFormat.java:355)
-125744830738000
-61916917138000
-61916917138000
	at com.tiza.ngp.rp.sanhui.util.Utils$TestRunnable.run(Utils.java:214)
	at java.lang.Thread.run(Thread.java:745)
java.lang.NumberFormatException: For input string: ""
	at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
	at java.lang.Long.parseLong(Long.java:453)

结果要么抛异常,要么结果为错误的负值。

二、简单分析

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public abstract class DateFormat extends Format {

    /**
     * The {@link Calendar} instance used for calculating the date-time fields
     * and the instant of time. This field is used for both formatting and
     * parsing.
     *
     * <p>Subclasses should initialize this field to a {@link Calendar}
     * appropriate for the {@link Locale} associated with this
     * <code>DateFormat</code>.
     * @serial
     */
    protected Calendar calendar;

    ...
}

DateFormat类使用了Calendar对象来维护parse和format过程中的日期时间值,当多线程同时使用同一个DateFormat对象,也就是多线程同时使用同一个Calendar对象来维护parse或format过程的日期时间值,必定会发生错乱。

引用Java api文档:

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.

三、解决方案

使用中要么为每个线程创建一个DateFormat实例,要么对其外部加锁。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Java日期处理易踩的十个坑
  我们设置了10小时,但运行结果是22点,而不是10点。因为Calendar.HOUR默认是按12小时制处理的,需要使用Calendar.HOUR_OF_DAY,因为它才是按24小时处理的。
不会飞的小鸟
2020/03/29
1.5K0
Java Review - SimpleDateFormat线程不安全原因的源码分析及解决办法
SimpleDateFormat是Java提供的一个格式化和解析日期的工具类,在日常开发中经常会用到,但是由于它是线程不安全的,所以多线程共用一个SimpleDateFormat实例对日期进行解析或者格式化会导致程序出错。
小小工匠
2021/11/22
5680
Java Review - SimpleDateFormat线程不安全原因的源码分析及解决办法
JUC学习之不可变
有很大几率出现 java.lang.NumberFormatException 或者出现不正确的日期解析结果,例如:
大忽悠爱学习
2022/01/10
2720
JUC学习之不可变
【优雅的避坑】不安全!别再共享SimpleDateFormat变量了-日期时间处理的正确姿势
JDK文档中已经明确表明了「SimpleDateFormat不应该用在多线程场景」中:
行百里er
2020/12/02
1K0
【优雅的避坑】不安全!别再共享SimpleDateFormat变量了-日期时间处理的正确姿势
JUC学习笔记——共享模型之不可变
但是我们可以选择更换一种日期类型,我们选择不可改变的日期类就可以完成并发下的数据修改问题:
秋落雨微凉
2022/11/21
3390
使用SimpleDateFormat的时候小心点
SimpleDateFormat是Java提供的一个格式化和解析日期的工具类,日常开发中应该经常会用到,但是由于它是线程不安全的,多线程公用一个SimpleDateFormat实例对日期进行解析或者格式化会导致程序出错。
chengcheng222e
2021/11/04
3310
SimpleDateFormat线程不安全示例及其解决方法
我们可以用java.text.SimpleDateFormat类完成日期的转换和格式化操作,如:
孟君
2019/10/10
1K0
ThreadLocal 你真的用不上吗?
点击上方“芋道源码”,选择“设为星标” 管她前浪,还是后浪? 能浪的浪,才是好浪! 每天 10:33 更新文章,每天掉亿点点头发... 源码精品专栏 原创 | Java 2021 超神之路,很肝~ 中文详细注释的开源项目 RPC 框架 Dubbo 源码解析 网络应用框架 Netty 源码解析 消息中间件 RocketMQ 源码解析 数据库中间件 Sharding-JDBC 和 MyCAT 源码解析 作业调度中间件 Elastic-Job 源码解析 分布式事务中间件 TCC-Transaction
芋道源码
2022/09/19
2900
ThreadLocal 你真的用不上吗?
SimpleDateFormat 线程安全问题
可以看到,多个线程之间共享变量calendar,并修改calendar。因此在多线程环境下,当多个线程同时使用相同的SimpleDateFormat对象(如static修饰)的话,如调用format方法时,多个线程会同时调用calender.setTime方法,导致time被别的线程修改,因此线程是不安全的。
王小明_HIT
2019/12/10
9510
SimpleDateFormat  线程安全问题
还在用SimpleDateFormat格式化时间?小心经理锤你
本来开开心心的周末时光,线上突然就疯狂报错,以为程序炸了,截停日志,发现是就是类似下述一段错误
拾荒者的笔记
2020/06/06
1.2K0
高并发之——SimpleDateFormat类的线程安全问题和解决方案
首先问大家一个问题:你使用的SimpleDateFormat类还安全吗?我们一起带着这个问题来看本文。
冰河
2020/10/29
2.4K0
更正《深入理解高并发编程(第1版)》中的一处错误!
最近,有小伙伴看了我写的《深入理解高并发编程(第1版)》或者在 冰河技术 公号看了《高并发之——SimpleDateFormat类的线程安全问题和解决方案》一文,对文中SimpleDateFormat类线程不安全问题的分析产生了疑惑,并留言或者私信我说明了自己对问题的理解和建议。
冰河
2021/03/24
1.7K0
深入理解Java:SimpleDateFormat安全的时间格式化
想必大家对SimpleDateFormat并不陌生。SimpleDateFormat 是 Java 中一个非常常用的类,该类用来对日期字符串进行解析和格式化输出,但如果使用不小心会导致非常微妙和难以调试的问题,因为 DateFormat 和 SimpleDateFormat 类不都是线程安全的,在多线程环境下调用 format() 和 parse() 方法应该使用同步代码来避免问题。下面我们通过一个具体的场景来一步步的深入学习和理解SimpleDateFormat类。
用户6182664
2019/09/05
1K0
Redis分布式锁故障,我忍不住想爆粗...
点击上方“芋道源码”,选择“设为星标” 管她前浪,还是后浪? 能浪的浪,才是好浪! 每天 10:33 更新文章,每天掉亿点点头发... 源码精品专栏 原创 | Java 2021 超神之路,很肝~ 中文详细注释的开源项目 RPC 框架 Dubbo 源码解析 网络应用框架 Netty 源码解析 消息中间件 RocketMQ 源码解析 数据库中间件 Sharding-JDBC 和 MyCAT 源码解析 作业调度中间件 Elastic-Job 源码解析 分布式事务中间件 TCC-Transaction
芋道源码
2022/07/12
3750
Redis分布式锁故障,我忍不住想爆粗...
SimpleDateFormat线程安全问题排查
SimpleDateFormat继承了DateFormat,DateFormat内部有一个Calendar对象的引用,主要用来存储和SimpleDateFormat相关的日期信息。
夕阳也是醉了
2023/10/16
3160
访问swagger文档报错Illegal DefaultValue 1024 for parameter type integer,java.lang.NumberFormatException
在AbstractSerializableParameter.getExample(AbstractSerializableParameter.java:412)打断点调试,可以发现代码执行到此处example的值为空字符串,执行Long.valueOf(this.example)会抛出’java.lang.NumberFormatException’ 异常。
共饮一杯无
2022/11/24
3620
访问swagger文档报错Illegal DefaultValue 1024 for parameter type integer,java.lang.NumberFormatException
JAVA日期安全格式化之SimpleDateFormat和jodaTime,DateTimeFormatter
SimpleDateFormat线程不安全的日期格式化库 SimpleDateFormat是JAVA提供的一个日期转换类。 package com.rumenz.task; import java.text.SimpleDateFormat; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; impor
开源日记
2021/01/28
6770
Swagger2.9.2进入API界面报NumberFormatException异常
原文出处:http://www.yund.tech/zdetail.html?type=1&id=dc9ac5bfa5b4d6348cb7e15e4edc3600 作者:jstarseven  问题发
大道七哥
2019/11/04
1.4K0
Swagger2.9.2进入API界面报NumberFormatException异常
Spring Boot中使用Swagger2异常:Illegal DefaultValue 0 for parameter type integer
在Spring Boot中集成Swagger2,使用@ApiImplicitParam注解时出现如下异常“Illegal DefaultValue 0 for parameter type integer”,异常详情如下:
程序新视界
2020/03/18
3.1K0
MarsTalk | 一次bug发现的Base64编码的用法
总结一下规律,发现`default`字段用的是ASSIC编码,如下图所示
HelloMin
2022/08/11
3650
MarsTalk |  一次bug发现的Base64编码的用法
推荐阅读
相关推荐
Java日期处理易踩的十个坑
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验