"DateFormat 不是同步的。建议为每个线程创建独立的格式实例。如果多个线程同时访问一个格式,则它必须保持外部同步。"----摘自JDK文档中文版
首先让我们看看一个简单的方法
public static Date toDate(String dateStr) { SimpleDateFormat p= new SimpleDateFormat("yyyyMMdd"); try{ return p.parse(dateStr); }catch (ParseException e) { } return null; }
这个方法是把形如"20110101"这样的字符串转换成Date类型;同时方法是支持多线程并发访问的,但是这个是有代价的,因为每次方法调用都要创建一个SimpleDateFormat 对象。
很自然的我们就想到以下的改进,将SimpleDateFormat声明为静态全局变量
private static final SimpleDateFormat PATTERN = new SimpleDateFormat("yyyyMMdd");
同时为了保证多线程同步访问,方法需要加锁
public synchronied static Date toDate(String dateStr) { try{ return PATTERN.parse(dateStr); }catch (ParseException e) { } return null; }
这样的优化还是不够的,因为在多线程争用的情况下,性能不佳。最好是每个线程都有自己的DateFormat,这样既不会发生争用,而且对于每个线程都只创建一个DateFormat对象。
ThreadLocal正好可以满足这种需求。这里不多做解释了,我们一步到位:
import java.text.SimpleDateFormat; import java.util.HashMap; import java.util.Map; public class DateFormatFactory { private static final Map<String, ThreadLocal<SimpleDateFormat>> pool = new HashMap<String, ThreadLocal<SimpleDateFormat>>(); private static final Object lock = new Object(); public static SimpleDateFormat getDateFormat(String pattern) { ThreadLocal<SimpleDateFormat> tl = pool.get(pattern); if (tl == null) { synchronized (lock) { tl = pool.get(pattern); if (tl == null) { final String p = pattern; tl = new ThreadLocal<SimpleDateFormat>() { protected synchronized SimpleDateFormat initialValue() { return new SimpleDateFormat(p); } }; pool.put(p, tl); } } } return tl.get(); } } public static Date toDate(String dateStr,String pattern) { try{ return getDateFormat(pattern).parse(dateStr); }catch (ParseException e) { } return null; }
上面还增加了对不同Pattern的ThreadLocal的缓存,这样对于每一个线程每一种pattern都只要创建一个SimpleDateFormat对象,多线程访问无需争用。
代码还要很多待改进的地方,如对于非法的pattern不要缓存,是否存在更快、更节约内存的方法。。。。。。
匆匆忙忙,如有错误的地方望不吝赐教!
相关推荐
总结来说,`DateFormat`的线程安全性问题要求开发者在多线程环境中特别注意其使用方式。通过理解这些潜在风险,我们可以采用适当的策略,如使用`ThreadLocal`,每次都创建新实例,或者切换到更现代的日期时间API,以...
然而,`DateFormat`并不是线程安全的,这意味着在多线程环境中直接使用可能会导致数据不一致或者异常。这篇博客文章《Java DateFormat并发实现》探讨了这个问题以及如何在并发环境下正确地使用`DateFormat`。 `...
在Java多线程编程中,`DateFormat`类是一个常见的日期和时间格式化工具,但它并不是线程安全的。这意味着在多线程环境下直接共享`DateFormat`实例可能会导致数据不一致或者异常。根据Java官方文档的建议,每个线程...
但是,如果使用不小心会导致非常微妙和难以调试的问题,因为DateFormat和SimpleDateFormat类不是线程安全的。在多线程环境下调用format()和parse()方法应该使用同步代码来避免问题。 知识点1: SimpleDateFormat的非...
如果需要在多线程环境下使用SimpleDateFormat,可以使用ThreadLocal或FastDateFormat确保线程安全。 Java SimpleDateFormat线程安全问题是Java开发中一个常见的问题。通过使用ThreadLocal或FastDateFormat,我们...
Java中的ThreadLocal是解决线程安全问题的一个重要工具,它提供了一种在多线程环境下为每个线程维护独立变量副本的方法,从而避免了共享状态带来的竞态条件和线程安全问题。 线程安全问题通常由全局变量和静态变量...
因为`Date`和`Calendar`类不是线程安全的,所以在多线程环境中使用时需要额外注意同步。另外,`SimpleDateFormat`是不可变的,但它的内部`DateFormat`是可变的,因此在多线程环境下,建议每个线程都拥有自己的`...
- **java.text.DateFormat**: 是一个抽象类,用于格式化日期和时间。`SimpleDateFormat`是其具体子类,可以自定义日期和时间的格式。 - **日期计算**: 对于复杂的日期计算,如加减天数,可以使用Calendar类的...
- 在高并发或多线程环境下使用 `DateFormat` 时,由于它是非线程安全的,需要通过同步机制来避免潜在的问题。例如,可以通过使用 `ThreadLocal` 来缓存每个线程的 `DateFormat` 实例。 4. **安全性问题**: - 当...
6. **线程安全的类与设计模式**:探讨了线程安全的设计模式,如单例模式、双重检查锁定、生产者消费者模型等,并分析了一些内置的线程安全类,如DateFormat、ThreadLocal等。 7. **并发编程的最佳实践**:书中总结...
要在高并发环境下能有比较好的体验,可以使用ThreadLocal来限制SimpleDateFormat只能在线程内共享,这样就避免了多线程导致的线程安全问题。 ```java private static ThreadLocal<DateFormat> threadLocal = new ...
本书覆盖了Java编程的各个方面,包括多线程、网络编程、I/O流、反射、集合框架、异常处理、国际化、安全、XML处理以及Java应用程序和Applet的开发等核心内容。以下是对这些主题的详细解释: 1. **多线程**:Java...
Multithreaded correctness: 多线程正确性 Performance:性能 Security:安全 Dodgy: 欺骗性代码 2、 常见Bug以及处理办法 a) 不需要处理 May expose internal representation by incorporating reference to mutable...
在Java 2平台上,类库主要分为几个关键部分:基础类库、集合框架、IO流、网络编程、多线程、异常处理、反射、安全性和国际化等。以下将分别对这些方面进行详细介绍: 1. **基础类库**:这是Java语言的基础,包括...
在上述文档中,我们看到四个不同的Java程序示例,分别涉及到基础的循环结构、条件判断、面向对象编程以及多线程与图形用户界面(GUI)。 1. **循环结构**:在第一个程序`Sum.java`中,使用了`for`循环来计算1到99...
1. SimpleDateFormat 是线程不安全的,因此在多线程环境下使用需要特别注意。 2. 创建 SimpleDateFormat 实例需要消耗大量的资源,因此应当尽量少创建实例。 3. SimpleDateFormat 可以使用 applyPattern 方法修改...
3. **多线程**:Java 6 API支持多线程编程,Thread类和Runnable接口是主要的多线程组件。通过继承Thread或实现Runnable,可以创建并管理多个并发执行的任务,利用多核处理器的性能。 4. **网络编程**:Java 6提供了...
需要注意的是,`SimpleDateFormat`不是线程安全的,所以在多线程环境中,如果多个线程同时使用一个`SimpleDateFormat`实例,可能会出现错误。为了避免这个问题,可以在每个线程内部创建单独的实例,或者使用`...
169 DateFormat 线程安全问题 170 登录页面底部链接问题 172 GAE 版配额消耗过快问题 177 泄漏用户密码安全问题 129 摘要编辑器添加源码功能 132 Markdown 编辑器显示问题 154 使用密文存储密码 155 邮件 SSL...