博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
DateFormat 线程不安全
阅读量:6691 次
发布时间:2019-06-25

本文共 2600 字,大约阅读时间需要 8 分钟。

hot3.png

一、测试

测试代码如下: 

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);                }            }        }    }

输出结果:

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)

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

二、简单分析

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.     *     * 

Subclasses should initialize this field to a {@link Calendar} * appropriate for the {@link Locale} associated with this * DateFormat. * @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实例,要么对其外部加锁。

 

转载于:https://my.oschina.net/shipley/blog/673212

你可能感兴趣的文章
教你如何攻克Kotlin中泛型型变的难点(实践篇)
查看>>
2018Android面试经历
查看>>
不受限对抗样本挑战赛介绍
查看>>
浅解前端必须掌握的算法(三):直接插入排序
查看>>
[译] TensorFlow 教程 #06 - CIFAR-10
查看>>
阅读SSH的ERP项目【第二篇】
查看>>
如何有效的避免OOM,温故Java中的引用
查看>>
NSHipster: NSRegularExpression 中文版
查看>>
Android 开发中不得不知道的 Tips 集合 (持续更新 ing)
查看>>
报警系统QuickAlarm之报警规则的设定与加载
查看>>
【CLI】使用 Curl 下载文件实时进度条显示
查看>>
Android 滤镜效果和颜色通道过滤
查看>>
Ruby开发者已可通过Fog管理Microsoft Azure服务
查看>>
Chrome和HTTPS:安全Web的征途
查看>>
软件专家的对话模式(第一部分)
查看>>
脚本填报表的条件查询
查看>>
从一个开发的角度看负载均衡和LVS
查看>>
Spring Boot(12)——使用MongoDB
查看>>
c++基础(上) 听课流水账
查看>>
Observable
查看>>