SimpleDateFormat 的线程安全问题

SimpleDateFormat不是线程安全的,作者建议每个线程使用独立实例。为确保线程安全,可以采取四种策略:1) 需要时创建对象;2) 使用`synchronized`同步;3) 利用`ThreadLocal`;4) 使用Java 8的线程安全API。其中,`ThreadLocal`是阿里巴巴开发手册推荐的实践方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

SimpleDateFormat 的作者在源码中就提到:

* Date formats are not synchronized.
* It is recommended to create separate format instances for each thread.
* If multiple threads access a format concurrently, it must be synchronized
* externally.

Date formats 不是同步的,需要对每个单独的线程创建各自的实例。如果多线程同时

使用同一个format的话,必须同步。

所以在使用SimpleDateFormat的时候就的特别注意,以下几种方式是保证线程安全

的使用方式:

一,使用的时候才创建对象:

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

    public static Date parse(String dateString)throws ParseException{
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
        return simpleDateFormat.parse(dateString);
    }

由于每次都是新建的对象,则可避免线程共享出现线程安全问题,但是频繁的创建销毁对象开销过大。

 

二,使用synchronized进行同步。

 public  static final SimpleDateFormat SIMPLE_DATE_FORMAT = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");

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

    public static Date parse(String dateString)throws ParseException{
        synchronized (SIMPLE_DATE_FORMAT){
            return SIMPLE_DATE_FORMAT.parse(dateString);
        }
    }

由于同步所以线程安全,但是很明显多个线阻塞性能不佳。

三,使用ThreadLocal。

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

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

    public static Date parse(String dateString)throws ParseException{
        return threadLocal.get().parse(dateString);
    }

这种用法也是《阿里巴巴开发手册》的推荐用法。

四,使用1.8新的线程安全的api

private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("MM/dd/yyyy HH:mm:ss");

    public static String formatDate(LocalDateTime date)throws ParseException{
        return FORMATTER.format(date);
    }

    public static LocalDateTime parse(String dateString)throws ParseException{
        return LocalDateTime.parse(dateString,FORMATTER);
    }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值