最近用到多线程写通信服务,发现在解析时间是一直莫名的错误,最后获取的时间和设备给我传输的时间经常不一致,时间有0144-12-12、2144-02-12等。很莫名其妙!
经过分析得出在转换时间时使用了SimpleDateFormat ,SimpleDateFormat是线程不安全的。
Tim Cull使用Threadlocal解决了此问题,对于每个线程SimpleDateFormat不存在影响他们之间协作的状态,为每个线程创建一个SimpleDateFormat变量的拷贝或者叫做副本,代码如下:
import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; /** * 使用ThreadLocal以空间换时间解决SimpleDateFormat线程安全问题。 * * @author * */ public class DateUtil { private static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss"; @SuppressWarnings("rawtypes") private static ThreadLocal threadLocal = new ThreadLocal() { protected synchronized Object initialValue() { return new SimpleDateFormat(DATE_FORMAT); } }; public static DateFormat getDateFormat() { return (DateFormat) threadLocal.get(); } public static Date parse(String textDate) throws ParseException { return getDateFormat().parse(textDate); } }
创建一个ThreadLocal类变量,这里创建时用了一个匿名类,覆盖了initialValue方法,主要作用是创建时初始化实例。也可以采用下面方式创建;
import java.text.DateFormat; import java.text.SimpleDateFormat; /** * 使用ThreadLocal以空间换时间解决SimpleDateFormat线程安全问题。 * * @author * */ public class DateUtil { private static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss"; // 第一次调用get将返回null private static ThreadLocal threadLocal = new ThreadLocal(); // 获取线程的变量副本,如果不覆盖initialValue,第一次get返回null,故需要初始化一个SimpleDateFormat,并set到threadLocal中 public static DateFormat getDateFormat() { DateFormat df = (DateFormat) threadLocal.get(); if (df == null) { df = new SimpleDateFormat(DATE_FORMAT); threadLocal.set(df); } return df; } }
我们看下我们覆盖的initialValue方法:
protected T initialValue() { return null;//直接返回null }
当然也可以使用:
apache commons-lang包的DateFormatUtils或者FastDateFormat实现,apache保证是线程安全的,并且更高效。
备注:没有找到相应的prase 方法。
相关推荐
在Java多线程环境下,SimpleDateFormat类的使用可能会出现线程安全问题。本文主要介绍了Java多线程环境下SimpleDateFormat类的安全转换,通过示例代码详细介绍了如何解决SimpleDateFormat类多线程环境下转换错误问题...
缓存机制使用了一个缓存数组来存储解析和格式化的结果,但是这个缓存数组是共享的,这意味着在多线程环境中,多个线程可能会同时访问和修改这个缓存数组,导致线程安全问题。 重现SimpleDateFormat类的线程安全问题...
目录SimpleDateFormat诡异bug复现SimpleDateFormat诡异bug字符串日期转Date日期(parse)Date日期转String类型(format)SimpleDateFormat出现bug的原因如何解决SimpleDateFormat多线程安全问题局部变量使用...
标题指出的"simpleDateFormat是线程不安全的",意味着在多线程环境下,如果多个线程共享同一个`SimpleDateFormat`实例,可能会引发数据不一致或异常。 `SimpleDateFormat`类的线程不安全主要源于以下几个原因: 1....
如果需要在多线程环境下使用SimpleDateFormat,可以使用ThreadLocal变量来保存每个线程的SimpleDateFormat实例。 知识点6: DateFormat和SimpleDateFormat类的区别 DateFormat和SimpleDateFormat类都是Java中用于...
然而,在多线程环境下,`SimpleDateFormat`存在非线程安全的问题,这可能会导致程序运行时出现异常或者错误的结果。 #### 二、问题分析 ##### 1. 非线程安全的原因 `SimpleDateFormat`类内部维护了一些线程不安全...
理解`SimpleDateFormat`的线程安全问题对于开发多线程应用程序至关重要。通过使用`ThreadLocal`、每次使用时创建新实例或切换到`java.time`包中的类,可以有效地避免这类问题,提高程序的稳定性和可靠性。在实际开发...
1. SimpleDateFormat 是线程不安全的,因此在多线程环境下使用需要特别注意。 2. 创建 SimpleDateFormat 实例需要消耗大量的资源,因此应当尽量少创建实例。 3. SimpleDateFormat 可以使用 applyPattern 方法修改...
在多线程环境下,不恰当的使用`DateFormat`可能导致数据不一致、性能下降甚至程序崩溃。这篇博客将深入探讨`DateFormat`在多线程环境下的问题及其解决方案。 `DateFormat`类在设计时并未被声明为线程安全的。这意味...
如果需要在多线程环境下使用SimpleDateFormat,可以使用ThreadLocal或FastDateFormat确保线程安全。 Java SimpleDateFormat线程安全问题是Java开发中一个常见的问题。通过使用ThreadLocal或FastDateFormat,我们...
在多线程环境下,SimpleDateFormat 由于其内部状态在格式化过程中可能会被多个线程修改,因此会出现线程不安全的现象。解决这一问题的方法有多种,包括将 SimpleDateFormat 定义为局部变量、使用 synchronized 或 ...
需要注意的是,由于`SimpleDateFormat`不是线程安全的,所以在多线程环境中,建议为每个线程创建单独的实例。 `Calendar`类则是Java中更底层的日期和时间工具,它提供了一套完整的API来操作日期和时间,包括添加、...
- `SimpleDateFormat`是线程不安全的,如果在多线程环境中使用,需要考虑同步问题。 - 日期和时间的格式化字符串要与实际情况对应,避免出现理解错误。 以上就是关于`SimpleDateFormat`的一些常见用法和注意事项,...
`SimpleDateFormat`不是线程安全的,所以在多线程环境中,要么为每个线程创建单独的实例,要么在每次使用后进行同步。 8. **替代方案**: Java 8引入了`java.time`包,其中的`DateTimeFormatter`类提供了更现代且...
Java标准库中有一些类,如ArrayList、HashMap和SimpleDateFormat,并未设计为线程安全,因此在多线程环境下直接使用可能导致数据不一致或其他问题。开发者应当了解每个类的线程安全特性,以便做出正确的选择和适当地...
需要注意的是,`SimpleDateFormat`不是线程安全的,因此在多线程环境中使用时,要么为每个线程创建独立的实例,要么使用`ThreadLocal`来存储实例。 此外,`SimpleDateFormat`也存在一些效率问题,因为它的解析过程...
`ThreadLocal`为每个线程提供了一个独立的变量副本,因此在多线程环境中,每个线程都可以安全地使用自己的`SimpleDateFormat`,而不会影响其他线程。 ```java class SimpleDateFormatThreadLocal { private static...
我们可以使用 `ScheduleConfig` 配置文件来实现多线程并发的定时任务。我们需要实现 `SchedulingConfigurer` 接口,并重写 `setScheduler` 方法来配置线程池。 ```java @Configuration public class ScheduleConfig...
然而,`DateFormat`并不是线程安全的,这意味着在多线程环境中直接使用可能会导致数据不一致或者异常。这篇博客文章《Java DateFormat并发实现》探讨了这个问题以及如何在并发环境下正确地使用`DateFormat`。 `...