ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

SimpleDateFormat线程不安全

2022-03-21 10:35:10  阅读:188  来源: 互联网

标签:... 调用 dateFormat SimpleDateFormat 安全 线程 time


在java8之前,我们对时间的格式化处理,一般都是用的SimpleDateFormat类实现的。例如:

@Service
public class SimpleDateFormatService {

    public Date time(String time) throws ParseException {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return dateFormat.parse(time);
    }
}

如果你真的这样写,是没问题的。

就怕哪天抽风,你觉得dateFormat是一段固定的代码,应该要把它抽取成常量。

于是把代码改成下面的这样:

@Service
public class SimpleDateFormatService {

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

    public Date time(String time) throws ParseException {
        return dateFormat.parse(time);
    }
}

dateFormat对象被定义成了静态常量,这样就能被所有对象共用。

如果只有一个线程调用time方法,也不会出现问题。

但Serivce类的方法,往往是被Controller类调用的,而Controller类的接口方法,则会被tomcat线程池调用。换句话说,可能会出现多个线程调用同一个Controller类的同一个方法,也就是会出现多个线程会同时调用time方法的情况。

而time方法会调用SimpleDateFormat类的parse方法:

@Override
public Date parse(String text, ParsePosition pos) {
    ...
    Date parsedDate;
    try {
        parsedDate = calb.establish(calendar).getTime();
        ...
    } catch (IllegalArgumentException e) {
        pos.errorIndex = start;
        pos.index = oldStart;
        return null;
    }
   return parsedDate;

该方法会调用establish方法:

Calendar establish(Calendar cal) {
    ...
    //1.清空数据
    cal.clear();
    //2.设置时间
    cal.set(...);
    //3.返回
    return cal;
}

其中的步骤1、2、3是非原子操作。

但如果cal对象是局部变量还好,坏就坏在parse方法调用establish方法时,传入的calendar是SimpleDateFormat类的父类DateFormat的成员变量:

public abstract class DateFormat extends Forma {
    ....
    protected Calendar calendar;
    ...
}

这样就可能会出现多个线程,同时修改同一个对象即:dateFormat,他的同一个成员变量即:Calendar值的情况。

这样可能会出现,某个线程设置好了时间,又被其他的线程修改了,从而出现时间错误的情况。

那么,如何解决这个问题呢?

  1. SimpleDateFormat类的对象不要定义成静态的,可以改成方法的局部变量。
  2. 使用ThreadLocal保存SimpleDateFormat类的数据。
  3. 使用java8的DateTimeFormatter类。

来自:

https://mp.weixin.qq.com/s/GCJaMeKiqyHd8okIP5Y_sQ

标签:...,调用,dateFormat,SimpleDateFormat,安全,线程,time
来源: https://www.cnblogs.com/dongdges/p/16033560.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有