Java在并发环境中SimpleDateFormat多种解决方案

 更新时间:2020年07月06日 10:40:24   作者:BarryW  
这篇文章主要介绍了Java在并发环境中SimpleDateFormat多种解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

先来看一个多线程下使用例子,看到运行结果会出现异常:

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
 
public class SimpleDateFormateTest {
 
  public static void main(String[] args) {
    final DateFormat df = new SimpleDateFormat("yyyyMMdd,HHmmss");
    ExecutorService ts = Executors.newFixedThreadPool(100);
    for (;;) {
      ts.execute(new Runnable() {     
        @Override
        public void run() {
          try {
           //生成随机数,格式化日期
           String format = df.format(new Date(Math.abs(new Random().nextLong())));
           System.out.println(format);
          } catch (Exception e) {
            e.printStackTrace();
            System.exit(1);
          }
        }
      });
    }
  }  
}

运行结果:

在并发环境下使用SimpleDateFormat,正常的打开放式如下:

为了能够在多线程环境下使用SimpleDateFormat,有这六种方法:

方法一

在需要执行格式化的地方都新建SimpleDateFormat实例,使用局部变量来存放SimpleDateFormat实例

public static String formatDate(Date date)throws ParseException{
 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
 return sdf.format(date);
}

这种方法可能会导致短期内创建大量的SimpleDateFormat实例,如解析一个excel表格里的字符串日期。

方法二

为了避免创建大量的SimpleDateFormat实例,往往会考虑把SimpleDateFormat实例设为静态成员变量,共享SimpleDateFormat对象。这种情况下就得对SimpleDateFormat添加同步。

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

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

这种方法的缺点也很明显,就是在高并发的环境下会导致解析被阻塞。

方法三 

方法加同步锁synchronized,在同一时刻,只有一个线程可以执行类中的某个方法。

缺点:性能较差,每次都要等待锁释放后其他线程才能进入。

方案四 使用第三方包

这个我有尝试cn.hutool和common-lang3提供的FastDateFormat
最后的结果其实并不满意,因为这两个包都没能帮助我检查非正常时间,比如2018-07-32这种日期也被认为是正确的时期格式了

方法五(推荐)

要在高并发环境下能有比较好的体验,可以使用ThreadLocal来限制SimpleDateFormat只能在线程内共享,这样就避免了多线程导致的线程安全问题。

 private static ThreadLocal<DateFormat> threadLocal = new ThreadLocal<DateFormat>() {
  @Override
  protected DateFormat initialValue() {
    return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  }
};

public static String format(Date date) {
  return threadLocal.get().format(date);
}

方案六 DateTimeFormatter使用

Java8提供了新的日期时间API,其中包括用于日期时间格式化的DateTimeFormatter,它与SimpleDateFormat的有什么区别呢?

问题解决

两者最大的区别是,Java8的DateTimeFormatter也是线程安全的,而SimpleDateFormat并不是线程安全。

解析日期

String dateStr= "2016年10月25日";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日");
LocalDate date= LocalDate.parse(dateStr, formatter);

日期转换为字符串

LocalDateTime now = LocalDateTime.now();
DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyy年MM月dd日 hh:mm a");
String nowStr = now .format(format);

由DateTimeFormatter的静态方法ofPattern()构建日期格式,LocalDateTime和LocalDate等一些表示日期或时间的类使用parse和format方法把日期和字符串做转换。

使用新的API,整个转换过程都不需要考虑线程安全的问题。

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

相关文章

  • SpringBoot Security权限控制自定义failureHandler实例

    SpringBoot Security权限控制自定义failureHandler实例

    这篇文章主要为大家介绍了SpringBoot Security权限控制自定义failureHandler实例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-11-11
  • Java实现两人五子棋游戏(五) 判断是否有一方胜出

    Java实现两人五子棋游戏(五) 判断是否有一方胜出

    这篇文章主要为大家详细介绍了Java实现两人五子棋游戏,判断是否有一方胜出,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-03-03
  • Spring实现IoC的多种方式小结

    Spring实现IoC的多种方式小结

    本篇文章主要介绍了Spring实现IoC的多种方式小结,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-02-02
  • SpringBoot配置开发环境的详细步骤(JDK、Maven、IDEA等)

    SpringBoot配置开发环境的详细步骤(JDK、Maven、IDEA等)

    文章介绍了如何配置SpringBoot开发环境,包括安装JDK、Maven和IDEA,并提供了详细的步骤和配置方法,感兴趣的朋友一起看看吧
    2024-12-12
  • 完美解决idea无法搜索下载插件的问题

    完美解决idea无法搜索下载插件的问题

    这篇文章主要介绍了完美解决idea无法搜索下载插件的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-09-09
  • Java学习关于循环和数组练习题整理

    Java学习关于循环和数组练习题整理

    在本篇文章里小编给各位整理了关于Java学习关于循环和数组练习题相关内容,有兴趣的朋友们跟着参考学习下。
    2019-07-07
  • 详解Spring系列之@ComponentScan自动扫描组件

    详解Spring系列之@ComponentScan自动扫描组件

    这篇文章主要介绍了Spring @ComponentScan自动扫描组件使用,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-06-06
  • java项目实现猜拳小游戏

    java项目实现猜拳小游戏

    这篇文章主要为大家详细介绍了java项目实现猜拳小游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-05-05
  • IDEA2020.1个性化设置的实现

    IDEA2020.1个性化设置的实现

    这篇文章主要介绍了IDEA2020.1个性化设置的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-08-08
  • Spring复杂对象创建的方式小结

    Spring复杂对象创建的方式小结

    这篇文章主要介绍了Spring复杂对象创建的三种方式,现在使用Spring如何创建这种类型的对象?Spring中提供了三种方法来创建复杂对象,需要的朋友可以参考下
    2022-01-01

最新评论