当前位置: 首页 > 网络应用技术

五个解决方案应对SimpleDateFormat线程不安全问题

时间:2023-03-05 20:14:59 网络应用技术

  摘要:我们知道SimpleDateFormat是不安全的线程。本文将介绍5种解决方案,以确保线程安全。

  在Java8之前,要格式化日期,您需要使用SimpleDateFormat。

  但是,我们知道SimpleDateFormat是不安全的线程。处理它时必须小心。您必须锁定或不能定义为静态。该对象在方法中可用并格式化。它非常麻烦,反复的新对象也增加了内存开销。

  让我们看一下SimpleDateFormat的源代码,首先查看格式方法:

  问题在于成员变量日历。如果使用SimpleDateFormat,请使用静态定义它,然后SimpleDateFormat将变为共享变量。calendar可以通过多个线程访问SimpleDateFormat。

  SimpleDateFormat的解析方法也是不安全的线程:

  可以从源代码中看到它,最后调用** parsedate = calb.espablish(calendar).getTime();**获取返回值。该方法的参数是日历,并且可以通过多个线程访问日历,并且存在不安全线程的问题。

  让我们看一下** calb.epblablish(日历)**的源代码

  calb.espblish(日历)方法连续称为cal.clear()和cal.set(),首先清理值,然后设置值。但是,这两个操作不是原子,也没有线程安全机制为了确保在多线程并发时,可能会导致CAL值的问题。

  false出现两次,表明该线程不安全。它仍然异常,这很严重。

  当使用SimpleDateFormat对象进行格式或解析时,它被定义为局部变量。它可以确保线程的安全性。

  从图可以看出,已保证线程安全性,但是不建议在高并发场景中使用此方案,因为将创建大量的简单构造对象来影响性能。

  SimpleDateFormat对象仍定义为全局变量,然后当需要简单的格式时间以进行格式化时间时,然后使用同步保证线程安全性。

  如图所示,线程是安全的。定义全局变量SimpleDateFormat,它减少了创建大量SimpleDateFormat对象的丢失。但是,使用同步锁,只有线程可以同时执行锁定代码块,这将影响高并发条件下的性能。但不建议在高点场景中使用此方案

  添加锁定锁和同步锁的原理是相同的,它们使用锁定机制来确保线程的安全性。

  从结果可以看出,添加锁定锁也可以确保线程安全性。应该注意的是,必须释放锁。该代码将lock.unlock()添加到决赛。

  在高并发状态的情况下,它将影响性能。不建议该方案在高的并发场景中使用

  使用ThreadLocal来确保每个线程都有SimpleDateFormat对象的副本。这可以确保线程的安全性。

  线路的使用可以确保线程安全性和效率。适合高并发场景。

  使用DateTimeFormatter而不是SimpleDateFormat(DateTimeFormatter是线程-Safe,Java 8+支持)

  DateTimeFormatter简介门户网站:Bowen教导您了解Java源代码的日期和时间用法

  使用DateTimeFormatter来确保线程安全性和效率很高。适合高并发场景。

  使用FastDateFormat替换SimpleDateFormat(FastDateFormat是线程-Safe,Apache Commons lang Package支持,不限于Java版本)

  使用FastDateFormat可以确保线程安全性和效率很高。适合高并发场景。

  源代码中的CALENDER是通过格式方法创建的,并且肯定不会发生Settime的线程安全问题。该线程安全疑问已解决。您必须考虑性能问题吗?

  让我们看看如何获得fastDateFormat

  查看相应的源代码

  这里有一个缓存,似乎使用了缓存,并且低头看。

  将cetinstance方法添加到contrentMap中以减慢和提高性能。我们知道consurrentMap也是线程 - 安全。

  如图所示,contrentMap用于缓存。关键值是格式,时区和语言环境(上下文)是相同的键。

  1.不要将其定义为静态变量,请使用局部变量

  2.锁定:同步锁和锁锁

  3.使用ThreadLocal方法

  4.使用DateTimeFormatter而不是SimpleDateFormat(DateTimeFormatter是线程-Safe,Java 8+支持)

  5.使用FastDateFormat替换SimpleDateFormat(FastDateFormat是线程-Safe,Apache Commons Lang支持,Java8之前建议使用此用法)

  本文分享了华为云社区的诚意,作者:xiaowuzhu。