`

SimpleDateFormat 多线程下解决

 
阅读更多

大致意思:Tim Cull碰到一个SimpleDateFormat带来的严重的性能问题,该问题主要有SimpleDateFormat引发,创建一个 SimpleDateFormat实例的开销比较昂贵,解析字符串时间时频繁创建生命周期短暂的实例导致性能低下。即使将 SimpleDateFormat定义为静态类变量,貌似能解决这个问题,但是SimpleDateFormat是非线程安全的,同样存在问题,如果用 ‘synchronized’线程同步同样面临问题,同步导致性能下降(线程之间序列化的获取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 方法。 

 

转摘自:http://www.cnblogs.com/icewee/articles/2017690.html

 

 

 

 

分享到:
评论
2 楼 JimmyLincole 2014-12-15  
tudopi 写道
用Threadlocal还不是每个线程实例都要new SimpleDateFormat,资源开销方面的优势在哪里呢?


while(true) {
   // 只创建一个SimpleDateFormat对象
   DateUtil.getDateFormat();
}

1 楼 tudopi 2013-04-19  
用Threadlocal还不是每个线程实例都要new SimpleDateFormat,资源开销方面的优势在哪里呢?

相关推荐

    simpleDateFormat是线程不安全的

    标题指出的"simpleDateFormat是线程不安全的",意味着在多线程环境下,如果多个线程共享同一个`SimpleDateFormat`实例,可能会引发数据不一致或异常。 `SimpleDateFormat`类的线程不安全主要源于以下几个原因: 1....

    ThreadLocal:如何优雅的解决SimpleDateFormat多线程安全问题

    目录SimpleDateFormat诡异bug复现SimpleDateFormat诡异bug字符串日期转Date日期(parse)Date日期转String类型(format)SimpleDateFormat出现bug的原因如何解决SimpleDateFormat多线程安全问题局部变量使用...

    高并发之-SimpleDateFormat类的线程安全问题和解决方案.docx

    缓存机制使用了一个缓存数组来存储解析和格式化的结果,但是这个缓存数组是共享的,这意味着在多线程环境中,多个线程可能会同时访问和修改这个缓存数组,导致线程安全问题。 重现SimpleDateFormat类的线程安全问题...

    详解SimpleDateFormat的线程安全问题与解决方案

    理解`SimpleDateFormat`的线程安全问题对于开发多线程应用程序至关重要。通过使用`ThreadLocal`、每次使用时创建新实例或切换到`java.time`包中的类,可以有效地避免这类问题,提高程序的稳定性和可靠性。在实际开发...

    关于SimpleDateFormat的非线程安全问题及其解决方案.docx

    ### 关于SimpleDateFormat的非线程安全问题及其解决方案 #### 一、问题介绍 在Java开发过程中,`...通过以上措施,可以有效地解决`SimpleDateFormat`在多线程环境下的非线程安全问题,提高程序的稳定性和可靠性。

    SimpleDateFormat线程不安全的5种解决方案.docx

    在多线程环境下,SimpleDateFormat 由于其内部状态在格式化过程中可能会被多个线程修改,因此会出现线程不安全的现象。解决这一问题的方法有多种,包括将 SimpleDateFormat 定义为局部变量、使用 synchronized 或 ...

    Java多线程环境下SimpleDateFormat类安全转换

    本文主要介绍了Java多线程环境下SimpleDateFormat类的安全转换,通过示例代码详细介绍了如何解决SimpleDateFormat类多线程环境下转换错误问题。 1. SimpleDateFormat类的线程安全问题 SimpleDateFormat类是Java中...

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

    SimpleDateFormat类不是线程安全的,这意味着在多线程环境下,如果多个线程同时访问同一个SimpleDateFormat实例,可能会导致各种问题,例如转化的时间不正确、报错、线程被挂死等等。 知识点2: 创建...

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

    在多线程环境下,如果多个线程同时使用同一个SimpleDateFormat对象,可能会导致日期时间格式化结果不正确或抛出异常。 问题的根源在于SimpleDateFormat的parse方法不是线程安全的。在多线程环境下,如果多个线程...

    DateFormat多线程问题

    这篇博客将深入探讨`DateFormat`在多线程环境下的问题及其解决方案。 `DateFormat`类在设计时并未被声明为线程安全的。这意味着当多个线程同时访问和修改同一个`DateFormat`实例时,可能会出现竞态条件,导致结果不...

    spring-boot 多线程并发定时任务的解决方案

    Spring Boot 多线程并发定时任务的解决方案 Spring Boot 提供了一个简单的方式来实现定时任务,使用 `@Scheduled` 注解可以轻松地实现定时任务。但是在实际开发中,我们需要实现多线程并发的定时任务,以提高任务...

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

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

    JavaSE 之 传统日期格式化的线程问题

    在上述代码的错误示例中,`Test1`类的`test01`方法创建了一个全局的`SimpleDateFormat`实例`sdf`,然后将其用于多线程环境。由于多个线程可能会同时调用`sdf.parse()`方法,这可能导致线程间的冲突,因为`...

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

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

    SimpleDateFormate格式说明.txt

    1. **格式化与解析**:`SimpleDateFormat`提供了一种方便的方式来格式化和解析日期,但需要注意的是,它不是线程安全的,如果在多线程环境中使用,应该考虑使用线程安全的`DateTimeFormatter`类。 2. **国际化问题**...

    Java多线程编程中使用DateFormat类

    这意味着在多线程环境下直接共享`DateFormat`实例可能会导致数据不一致或者异常。根据Java官方文档的建议,每个线程应该拥有自己独立的日期格式实例,或者在访问`DateFormat`时进行适当的同步控制,以避免并发问题。...

    Java DateFormat并发实现

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

    深入理解高并发编程-Java线程池核心技术

    为了解决这一问题,我们可以使用线程局部变量(ThreadLocal)或者在每次使用时实例化新的SimpleDateFormat对象,避免在多线程环境下共享同一实例。 线程池的引入是为了克服直接创建线程的弊端,如线程创建和销毁的...

    李兴华java1.8视频笔记

    它描述了在多线程环境下,一个或多个生产者线程产生数据放到缓冲区,一个或多个消费者线程从缓冲区取出数据进行处理的模型。在该模型中,需要解决数据错乱问题,通常采用同步机制来处理。 在Java基础类库中,有多个...

Global site tag (gtag.js) - Google Analytics