转自自己的博客:http://onedear.cn/entry/dateFormat_synchronized.html
最近一个系统总是会出现一些异常数据。那个系统处理逻辑不复杂。这里用自己的话语大致描述下:系统在数据处理时用上了key-value缓存框架,由于 数据需要时效性,于是用系统名+时间做组合key,例如原有系统名是“system”,那加上时间的key是:system20100101
12:00:00 .时间是精确到小时的,这里调用的方法是key = "system"+
DateUtil.dateToString(DateUtil.getDayTIme(date));
这里贴下自己精简后的util类
/**
* @author onedear
*
*/
public final class DateUtil {
private static DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
public static String dateToString(Date date) {
return sdf.format(date);
}
/**
* 返回天key
* @return
*/
public static Date getDayTime(Date date) {
Calendar cal = new GregorianCalendar();
cal.setTime(date);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
return cal.getTime();
}
}
但在实际跑的时候,这个组合key总会出现一点不可思议的数据:
如 system20100101 12:12:13 ,时间竟然不是精确到小时!
由于系统是多线程跑,发现问题总是要花费很多时间,在写了n多log后,发现可能是DateUtil工具类出现问题。
这个工具类是很久之前写的,一直没发现有什么问题。但问题明明就出现在这里,最终查jdk的DateFormat说明,发现dateFormat不是线程安全的:
Synchronization
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.
那异常数据肯定是被其他线程修改了,最后改成
public static synchronized String dateToString(Date date) {
return sdf.format(date);
}
系统正常跑动。困扰几天的问题总算解决了!
分享到:
相关推荐
在多线程环境下,不恰当的使用`DateFormat`可能导致数据不一致、性能下降甚至程序崩溃。这篇博客将深入探讨`DateFormat`在多线程环境下的问题及其解决方案。 `DateFormat`类在设计时并未被声明为线程安全的。这意味...
然而,`DateFormat`并不是线程安全的,这意味着在多线程环境中直接使用可能会导致数据不一致或者异常。这篇博客文章《Java DateFormat并发实现》探讨了这个问题以及如何在并发环境下正确地使用`DateFormat`。 `...
在Java多线程编程中,`DateFormat`类是一个常见的日期和时间格式化工具,但它并不是线程安全的。这意味着在多线程环境下直接共享`DateFormat`实例可能会导致数据不一致或者异常。根据Java官方文档的建议,每个线程...
但是,如果使用不小心会导致非常微妙和难以调试的问题,因为DateFormat和SimpleDateFormat类不是线程安全的。在多线程环境下调用format()和parse()方法应该使用同步代码来避免问题。 知识点1: SimpleDateFormat的非...
在多线程环境下,如果多个线程同时使用同一个SimpleDateFormat对象,可能会导致日期时间格式化结果不正确或抛出异常。 问题的根源在于SimpleDateFormat的parse方法不是线程安全的。在多线程环境下,如果多个线程...
线程安全问题通常由全局变量和静态变量引起,因为这些变量在整个程序运行期间只有一份,多个线程可能同时访问并修改它们,从而导致数据不一致或错误。例如,`SimpleDateFormat` 是非线程安全的,因为它内部使用了一...
另外,`SimpleDateFormat`是不可变的,但它的内部`DateFormat`是可变的,因此在多线程环境下,建议每个线程都拥有自己的`SimpleDateFormat`实例。 为了提高效率和简化日期时间处理,Java 8引入了`java.time`包,...
Multithreaded correctness: 多线程正确性 Performance:性能 Security:安全 Dodgy: 欺骗性代码 2、 常见Bug以及处理办法 a) 不需要处理 May expose internal representation by incorporating reference to mutable...
- **java.text.DateFormat**: 是一个抽象类,用于格式化日期和时间。`SimpleDateFormat`是其具体子类,可以自定义日期和时间的格式。 - **日期计算**: 对于复杂的日期计算,如加减天数,可以使用Calendar类的...
本书覆盖了Java编程的各个方面,包括多线程、网络编程、I/O流、反射、集合框架、异常处理、国际化、安全、XML处理以及Java应用程序和Applet的开发等核心内容。以下是对这些主题的详细解释: 1. **多线程**:Java...
- 在高并发或多线程环境下使用 `DateFormat` 时,由于它是非线程安全的,需要通过同步机制来避免潜在的问题。例如,可以通过使用 `ThreadLocal` 来缓存每个线程的 `DateFormat` 实例。 4. **安全性问题**: - 当...
要在高并发环境下能有比较好的体验,可以使用ThreadLocal来限制SimpleDateFormat只能在线程内共享,这样就避免了多线程导致的线程安全问题。 ```java private static ThreadLocal<DateFormat> threadLocal = new ...
1. SimpleDateFormat 是线程不安全的,因此在多线程环境下使用需要特别注意。 2. 创建 SimpleDateFormat 实例需要消耗大量的资源,因此应当尽量少创建实例。 3. SimpleDateFormat 可以使用 applyPattern 方法修改...
6. **线程安全的类与设计模式**:探讨了线程安全的设计模式,如单例模式、双重检查锁定、生产者消费者模型等,并分析了一些内置的线程安全类,如DateFormat、ThreadLocal等。 7. **并发编程的最佳实践**:书中总结...
在Java 2平台上,类库主要分为几个关键部分:基础类库、集合框架、IO流、网络编程、多线程、异常处理、反射、安全性和国际化等。以下将分别对这些方面进行详细介绍: 1. **基础类库**:这是Java语言的基础,包括...
在上述文档中,我们看到四个不同的Java程序示例,分别涉及到基础的循环结构、条件判断、面向对象编程以及多线程与图形用户界面(GUI)。 1. **循环结构**:在第一个程序`Sum.java`中,使用了`for`循环来计算1到99...
这个类是线程不安全的,因此在多线程环境中,建议每个线程拥有自己的`SimpleDateFormat`实例。 `SimpleDateFormat`的构造函数允许程序员传入一个字符串模式,这个模式定义了日期和时间的显示格式。例如,`"yyyy年MM...
- **描述**:这会导致在多线程环境中出现不一致的状态。 - **处理**:确保访问共享资源的方法都同步。 - **Unconditional wait**:无条件的wait。 - **描述**:线程在没有条件的情况下等待,可能会导致死锁。 -...
它分为几个主要部分,如核心类库、集合框架、I/O流、网络编程、多线程、反射、异常处理、国际化、安全管理以及JDBC等。这些部分涵盖了Java开发中的各个方面,帮助开发者了解如何使用Java提供的各种功能。 1. **核心...