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

最近看到一篇文章提到了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。

猜你喜欢

转载自blog.csdn.net/github_39538842/article/details/89354360