首页 > 其他分享 >多线程避免使用SimpleDateFormat及替代方案

多线程避免使用SimpleDateFormat及替代方案

时间:2023-07-02 16:33:14浏览次数:46  
标签:String format SimpleDateFormat DateTimeFormatter date new 多线程 替代

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

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,整个转换过程都不需要考虑线程安全的问题。

标签:String,format,SimpleDateFormat,DateTimeFormatter,date,new,多线程,替代
From: https://blog.51cto.com/u_16110904/6605829

相关文章

  • SimpleDateFormat的setLenient(true或false)-----自动计算日期
    有时候我们需要判断用户的日期格式是否正确,虽然绝大多数会在前台处理,但是也有需要从文件流读入的情况,如果日期不合格就需要抛异常,这时候就需要禁止SimpleDateFormat的自动计算功能。此时就需要用到setLenient(),这个方法的含义是是否严格解析日期,具体用法如下。packagecom.test.......
  • django优缺点 # ninja的优点可替代DRF
    摘抄:https://www.cnblogs.com/fnng/p/16084825.htmldjango优点通过脚手架创建项目/应用:不用考虑项目架构怎么设计。自带Admin后台:在没有前端的情况下,可以比较方便通过Admin对数据进行操作。自带常用模块:一个命令就能生成group、user、session...表,一般个系统都需要user表吧......
  • 创建多线程程序两种方式的区别
    1、使用实现Runnable接口的方式创建多线程程序,可以避免单继承的局限性a.类继承了Thread类,就不能在继承其他的类了b.类实现了Runnable接口,还可以继承其他的类2、使用实现Runnable接口的方式创建多线程程序,可以把设置线程任务和开启线程进行解耦(解除了耦合性,增强......
  • CentOS Linux的最佳替代方案(三)_银河麒麟Kylin Linux Advanced Server V10 SP2 for X86
    CentOSLinux的最佳替代方案(三)_银河麒麟KylinLinuxAdvancedServerV10SP2forX86安装教程1银河麒麟KylinLinuxAdvancedServerV10简介银河麒麟高级服务器操作系统V10是针对企业级关键业务,适应虚拟化、云计算、大数据、工业互联网时代对主机系统可靠性、安全性、性能、扩......
  • 浅谈一下c#多线程编程
    概念线程:线程是操作系统能够进行运算调度的最小单位,被包含在进程之中,是进程中的实际运作单位。同步:一定要等任务执行完了,得到结果,才执行下一个任务。如果程序执行耗时操作时会阻塞线程。应用场景UI与I/O:UI发出I/O操作,I/O操作是费时任务计算密集型工作(CPU-boun......
  • 高并发场景下,6种解决SimpleDateFormat类的线程安全问题方法
    摘要:解决SimpleDateFormat类在高并发场景下的线程安全问题可以有多种方式,这里,就列举几个常用的方式供参考。本文分享自华为云社区《【高并发】更正SimpleDateFormat类线程不安全问题分析的错误》,作者:冰河。解决SimpleDateFormat类在高并发场景下的线程安全问题可以有多种方式......
  • 高并发场景下,6种解决SimpleDateFormat类的线程安全问题方法
    摘要:解决SimpleDateFormat类在高并发场景下的线程安全问题可以有多种方式,这里,就列举几个常用的方式供参考。本文分享自华为云社区《【高并发】更正SimpleDateFormat类线程不安全问题分析的错误》,作者:冰河。解决SimpleDateFormat类在高并发场景下的线程安全问题可以有多种方式,这......
  • MFC中使用多线程
    一、在MFC中使用多线程,可以通过CWinThread类来实现。下面是一个简单的示例,演示了如何在MFC应用程序中创建和使用多线程:在你的MFC应用程序中包含头文件"afxmt.h",该头文件包含了多线程相关的类和函数。创建一个派生自CWinThread的自定义线程类。示例代码如下:classMyThrea......
  • 多线程
          ......
  • C多线程
          ......