java中SimpleDateFormater线程安全问题及解决方案

本文探讨了SimpleDateFormat在多线程环境下的线程安全问题,分析其内部原因,并提供三种解决方案:避免共享实例、使用ThreadLocal,以及推荐采用java8的LocalDateTime进行日期处理,附带详细介绍LocalDateTime的常用API。

最近看到一篇文章提到了SimpleDateFormater这个类。说这个类在单线程程序中没问题,但是在多线程环境下会线程安全的问题。

出于兴趣对这个问题进行了查证。网上有很多关于这个问题的文章,也解析了其中的原因。主要原因是因为SimpleDateFormat转换日期是通过Calendar对象来操作的,SimpleDateFormat继承DateFormat类,DateFormat类中维护一个Calendar对象,当多个线程同时操作这个对象时就会出现问题。

那么解决的办法呢?。有以下几种

1.在使用SimpleDateFormater时候尽量不要共享,每次使用的时候都创建一个新的对象

2.使用ThreadLocal来包装一下formater对象

        ThreadLocal<SimpleDateFormat> local = new ThreadLocal<>();
        SimpleDateFormat sdf =  local.get();

3.使用LocalDateTime这个类来进行日期转换和处理(推荐)

针对第三种方法,重点介绍一下这个类。

这个类诶是java8推出的一个日期处理的工具类,在Time包下。

主要有三个类LocalDate,LocalTime,LocalDateTime。第一个是针对年月日,第二个针对时分秒,第三个是年月日加时分秒

这里以LocalDateTime为例,列举一些方法

        //获取当前时间
        LocalDateTime ldt = LocalDateTime.now();
        //给定年月日时分秒获取时间
        LocalDateTime ldt2 = LocalDateTime.of(2019, 1, 1, 1, 1, 1);
        //给定年月日时分秒毫秒获取时间
        LocalDateTime ldt3 = LocalDateTime.of(2019, 1, 1, 1, 1, 1, 1);
        //给时间字符串获取时间
        LocalDateTime ldt4 = LocalDateTime.parse("2019-01-10T17:07:05");
        //获取LocalDateTime对象当月的第一天
        LocalDateTime firstDayOfThisMonth = ldt4.with(TemporalAdjusters.firstDayOfMonth());
        //获取LocalDateTime对象当月的第二天
        LocalDateTime secondDayOfThisMonth = ldt4.withDayOfMonth(2);
        //获取LocalDateTime对象当月的最后一天
        LocalDateTime lastDayOfThisMonth = ldt4.with(TemporalAdjusters.lastDayOfMonth());
        //获取LocalDateTime对象的后一天
        LocalDateTime newtDay = ldt4.plusDays(1);
        //获取LocalDateTime对象的当月第一个周一
        LocalDateTime firstMondayOfDay = ldt4.with(TemporalAdjusters.firstInMonth(DayOfWeek.MONDAY));

        //获取LocalDateTime对象的年,月,日
        int year = ldt4.getYear();
        int month = ldt4.getMonthValue();
        int day = ldt4.getDayOfMonth();


        //前一天
        LocalDate l2 = ld.minusDays(1);
        //后一天
        LocalDate l3 = ld.plusDays(1);

这些是一些经常用到的方法,还有很多方法没有列出,感兴趣的可以去查找一个官方api。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值