`

让DateFormat多线程安全

    博客分类:
  • J2EE
阅读更多

"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多线程问题

    总结来说,`DateFormat`的线程安全性问题要求开发者在多线程环境中特别注意其使用方式。通过理解这些潜在风险,我们可以采用适当的策略,如使用`ThreadLocal`,每次都创建新实例,或者切换到更现代的日期时间API,以...

    Java DateFormat并发实现

    然而,`DateFormat`并不是线程安全的,这意味着在多线程环境中直接使用可能会导致数据不一致或者异常。这篇博客文章《Java DateFormat并发实现》探讨了这个问题以及如何在并发环境下正确地使用`DateFormat`。 `...

    Java多线程编程中使用DateFormat类

    在Java多线程编程中,`DateFormat`类是一个常见的日期和时间格式化工具,但它并不是线程安全的。这意味着在多线程环境下直接共享`DateFormat`实例可能会导致数据不一致或者异常。根据Java官方文档的建议,每个线程...

    深入理解Java:SimpleDateFormat安全的时间格式化

    但是,如果使用不小心会导致非常微妙和难以调试的问题,因为DateFormat和SimpleDateFormat类不是线程安全的。在多线程环境下调用format()和parse()方法应该使用同步代码来避免问题。 知识点1: SimpleDateFormat的非...

    Java SimpleDateFormat线程安全问题原理详解

    如果需要在多线程环境下使用SimpleDateFormat,可以使用ThreadLocal或FastDateFormat确保线程安全。 Java SimpleDateFormat线程安全问题是Java开发中一个常见的问题。通过使用ThreadLocal或FastDateFormat,我们...

    Java ThreadLocal 线程安全问题解决方案

    Java中的ThreadLocal是解决线程安全问题的一个重要工具,它提供了一种在多线程环境下为每个线程维护独立变量副本的方法,从而避免了共享状态带来的竞态条件和线程安全问题。 线程安全问题通常由全局变量和静态变量...

    Java日期时间使用总结及项目中遇到的问题

    因为`Date`和`Calendar`类不是线程安全的,所以在多线程环境中使用时需要额外注意同步。另外,`SimpleDateFormat`是不可变的,但它的内部`DateFormat`是可变的,因此在多线程环境下,建议每个线程都拥有自己的`...

    解析Date & Calendar类

    - **java.text.DateFormat**: 是一个抽象类,用于格式化日期和时间。`SimpleDateFormat`是其具体子类,可以自定义日期和时间的格式。 - **日期计算**: 对于复杂的日期计算,如加减天数,可以使用Calendar类的...

    获取当前时间

    - 在高并发或多线程环境下使用 `DateFormat` 时,由于它是非线程安全的,需要通过同步机制来避免潜在的问题。例如,可以通过使用 `ThreadLocal` 来缓存每个线程的 `DateFormat` 实例。 4. **安全性问题**: - 当...

    Java并发编程实战(中文版).7z

    6. **线程安全的类与设计模式**:探讨了线程安全的设计模式,如单例模式、双重检查锁定、生产者消费者模型等,并分析了一些内置的线程安全类,如DateFormat、ThreadLocal等。 7. **并发编程的最佳实践**:书中总结...

    Java在并发环境中SimpleDateFormat多种解决方案

    要在高并发环境下能有比较好的体验,可以使用ThreadLocal来限制SimpleDateFormat只能在线程内共享,这样就避免了多线程导致的线程安全问题。 ```java private static ThreadLocal&lt;DateFormat&gt; threadLocal = new ...

    核心Java 2 第2卷(第7版)

    本书覆盖了Java编程的各个方面,包括多线程、网络编程、I/O流、反射、集合框架、异常处理、国际化、安全、XML处理以及Java应用程序和Applet的开发等核心内容。以下是对这些主题的详细解释: 1. **多线程**:Java...

    findbug 常见异常处理

    Multithreaded correctness: 多线程正确性 Performance:性能 Security:安全 Dodgy: 欺骗性代码 2、 常见Bug以及处理办法 a) 不需要处理 May expose internal representation by incorporating reference to mutable...

    Java2 类库参考手册-pdf.zip

    在Java 2平台上,类库主要分为几个关键部分:基础类库、集合框架、IO流、网络编程、多线程、异常处理、反射、安全性和国际化等。以下将分别对这些方面进行详细介绍: 1. **基础类库**:这是Java语言的基础,包括...

    java程序的设计的编程.doc

    在上述文档中,我们看到四个不同的Java程序示例,分别涉及到基础的循环结构、条件判断、面向对象编程以及多线程与图形用户界面(GUI)。 1. **循环结构**:在第一个程序`Sum.java`中,使用了`for`循环来计算1到99...

    由浅入深解析 SimpleDateFormat

    1. SimpleDateFormat 是线程不安全的,因此在多线程环境下使用需要特别注意。 2. 创建 SimpleDateFormat 实例需要消耗大量的资源,因此应当尽量少创建实例。 3. SimpleDateFormat 可以使用 applyPattern 方法修改...

    java 6 api

    3. **多线程**:Java 6 API支持多线程编程,Thread类和Runnable接口是主要的多线程组件。通过继承Thread或实现Runnable,可以创建并管理多个并发执行的任务,利用多核处理器的性能。 4. **网络编程**:Java 6提供了...

    Java中SimpleDateFormat用法详解

    需要注意的是,`SimpleDateFormat`不是线程安全的,所以在多线程环境中,如果多个线程同时使用一个`SimpleDateFormat`实例,可能会出现错误。为了避免这个问题,可以在每个线程内部创建单独的实例,或者使用`...

    B3LOG Solo v1.0.0 for MySQL.zip

    169 DateFormat 线程安全问题 170 登录页面底部链接问题 172 GAE 版配额消耗过快问题 177 泄漏用户密码安全问题 129 摘要编辑器添加源码功能 132 Markdown 编辑器显示问题 154 使用密文存储密码 155 邮件 SSL...

Global site tag (gtag.js) - Google Analytics