Java SimpleDateFormat线程安全问题原理详解

 更新时间:2020年05月13日 14:54:31   作者:玄同太子  
这篇文章主要介绍了Java SimpleDateFormat线程安全问题原理详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

今天百度一些资料偶然发现SimpleDateFormat居然不是线程安全的,平时使用时根本没有考虑,万幸今天发现了这个问题,得把写的代码得翻出来整理一下了。

一般我们使用的SimpleDateFormat一般是这样写的:

public void method() {
  ...
  DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  Date date = dateFormat.parse("2020-05-10 19:53:00");
  ...
}

这样写完全没有任何问题,但我们有时候会觉得重复创建SimpleDateFormat耗费性能,就想到把SimpleDateFormat对象做为类的静态成员变量,那么代码就是这样了:

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

public void method() {
  ...
  Date date = dateFormat.parse("2020-05-10 19:53:00");
  ...
}

我经常在Controller做日期转换的时候就是这么干的,但这样写很有问题,多线程通知执行容易出问题,要么转换后的结果不对,要么报错,我们测试一下:

public class DateUtils {
  private static final DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

  public static Date prase(String date) throws ParseException {
    return dateFormat.parse(date);
  }

  static class Job extends Thread {
    @Override
    public void run() {
      try {
        System.out.println(this.getName() + ":" + DateUtils.prase("2020-05-10 19:53:00"));
      } catch (ParseException e) {
      }
    }
  }

  public static void main(String[] args) {
    for (int i = 0; i < 10; i++) {
      new Job().start();
    }
  }
}

测试结果如下:

那有没有好的解决方案呢,既不用重复创建对象,又保证线程安全呢?答案是有。

方法一:使用ThreadLocal

public class MyController {
  private static ThreadLocal<DateFormat> local = new ThreadLocal<DateFormat>() {
    protected DateFormat initialValue() {
      return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    };
  };
  
  public void method() {
    ...
    Date date = local.get().parse("2020-05-10 19:53:00");
    ...
  }
}

方法二:使用第三方apache提供工具包commons-lang3

import org.apache.commons.lang3.time.FastDateFormat;
public class MyController {
  public void method() {
    ...
    Date date = FastDateFormat.getInstance("yyyy-MM-dd HH:mm:ss").parse("2020-05-10 19:53:00");
    ...
  }
}

推荐使用第二种,既快有方便。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • java poi导出图片到excel示例代码

    java poi导出图片到excel示例代码

    这篇文章主要介绍java poi如何导出图片到excel,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-03-03
  • Springboot中配置Mail和普通mail的实现方式

    Springboot中配置Mail和普通mail的实现方式

    这篇文章主要介绍了Springboot中配置Mail和普通mail的实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-03-03
  • 图解JAVA中Spring Aop作用

    图解JAVA中Spring Aop作用

    这篇文章主要介绍了Java的Spring框架下的AOP的作用,需要的朋友可以参考
    2017-04-04
  • Java注解机制之Spring自动装配实现原理详解

    Java注解机制之Spring自动装配实现原理详解

    这篇文章主要为大家详细介绍了Java注解机制之Spring自动装配实现原理,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-10-10
  • SpringBoot 下在 yml 中的 logging 日志配置方法

    SpringBoot 下在 yml 中的 logging 日志配置方法

    logging 配置主要用于控制应用程序的日志输出行为,可以通过配置定制日志的格式、级别、输出位置等,这篇文章主要介绍了SpringBoot 下在 yml 中的 logging 日志配置,需要的朋友可以参考下
    2024-06-06
  • java环境变量为什么要配置path和classpath详细解答

    java环境变量为什么要配置path和classpath详细解答

    为何配置path?为何配置classpath?当时初学java时只是关心如何做而不去关心这些问题,接下来介绍一下,感兴趣的朋友可以参考下哦
    2013-01-01
  • 简单了解spring bean的循环引用

    简单了解spring bean的循环引用

    这篇文章主要介绍了简单了解spring bean的循环引用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-08-08
  • Spring启动时实现初始化有哪些方式?

    Spring启动时实现初始化有哪些方式?

    今天给大家带来的文章是关于Spring的相关知识,文章围绕着Spring启动时实现初始化有哪些方式展开,文中有非常详细的介绍,需要的朋友可以参考下
    2021-06-06
  • mybatis 一对多映射 column属性的注意事项说明

    mybatis 一对多映射 column属性的注意事项说明

    这篇文章主要介绍了mybatis 一对多映射 column属性的注意事项说明,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教。
    2022-01-01
  • 一文解决pom.xml报错Dependency "xxx" not found的问题

    一文解决pom.xml报错Dependency "xxx" not f

    我们在使用maven进行jar包管理时有时会遇到pom.xml中报错Dependency “XXX” not found,所以在本文中将给大家介绍一下pom.xml报错Dependency "xxx" not found的解决方案,需要的朋友可以参考下
    2024-01-01

最新评论