多线程下调用SimpleDateFormat的问题

SimpleDateFormat类用于时间格式的处理:

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd", Locale.CHINA);// 输出北京时间
String currentNetworkTime = "2017-09-19";
Date date_from_network = Constants.sdf.parse(currentNetworkTime);

结果:

date_from_network:Tue Sep 19 00:00:00 GMT+08:00 2017

parse可以将简单的时间字符串转换成标准的时间格式,然而

SimpleDateFormat不是线程安全的

做了这样一个测试,固定输入,开启100个线程进行时间格式转换:

            for (int i = 0 ;i<100;i++){
                    Thread thread = new Thread(new Runnable() {
                        @Override
                        public void run() {
                            String currentNetworkTime = "2017-09-19";
                            try {
                                Log.i(CLASS_TAG, "currentNetworkTime:" + currentNetworkTime);
                                Date date_from_network = Constants.sdf.parse(currentNetworkTime);
                                Log.i(CLASS_TAG, "date_from_network:" + date_from_network);
                            } catch (ParseException e) {
                                e.printStackTrace();
                            }

                        }
                    });
                    thread.start();
                }

然后其中一些线程会出现异常:

09-19 10:35:36.889 26529 27665 I ecm_ecms: ->EcmServiceManager:currentNetworkTime:2017-09-19

09-19 10:35:36.890 26529 27665 I ecm_ecms: ->EcmServiceManager:date_from_network:

09-19 10:35:36.890 26529 27665 I ecm_ecms: ->EcmServiceManager: date_from_network:Fri Sep 11 00:00:00 GMT+08:00 2201

第一次打印结果居然是空的,第二次打印结果居然是2201年!
当然最好的改法是把SimpleDateFormat重新做一次封装,然后替换:


import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class DateSyncUtil {

    private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    public static String format(Date date)throws ParseException{
        synchronized(sdf){
            return sdf.format(date);
        }  
    }

    public static Date parse(String strDate) throws ParseException{
        synchronized(sdf){
            return sdf.parse(strDate);
        }
    } 
}

后记:
一开始从日志里根本看不出什么问题,用日志里面的数据重新测试也无法复现,后来发现这部分代码在相同时间内调用了两次才怀疑是多线程并发引起的,然后从上层模拟多线程调用,发现当线程数量增大后结果竟然有一定随机性,增加打印,进一步缩小范围最后才定位到是SimpleDateFormat原因。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值