Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/401.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用ThreadLocal进行日期转换_Java_Simpledateformat_Date Conversion - Fatal编程技术网

Java 使用ThreadLocal进行日期转换

Java 使用ThreadLocal进行日期转换,java,simpledateformat,date-conversion,Java,Simpledateformat,Date Conversion,我需要将输入日期字符串格式“20130212”(YYYYMMDD)转换为2013年2月12日(DD/MM/YYYY) 使用ThreadLocal。我知道一种不用ThreadLocal的方法。有人能帮我吗 不带ThreadLocal的转换: final SimpleDateFormat format2 = new SimpleDateFormat("MM/dd/yyyy"); final SimpleDateFormat format1 = new SimpleDateFormat

我需要将输入日期字符串格式“20130212”(YYYYMMDD)转换为2013年2月12日(DD/MM/YYYY)

使用
ThreadLocal
。我知道一种不用
ThreadLocal
的方法。有人能帮我吗

不带
ThreadLocal的转换

    final SimpleDateFormat format2 = new SimpleDateFormat("MM/dd/yyyy");
    final SimpleDateFormat format1 = new SimpleDateFormat("yyyyMMdd");
    final Date date = format1.parse(tradeDate);
    final Date formattedDate = format2.parse(format2.format(date));

这背后的想法是SimpleDataFormat不是线程安全的,因此在多线程应用程序中,您不能在多个线程之间共享SimpleDataFormat的实例。但由于SimpleDataFormat的创建是一项昂贵的操作,我们可以使用ThreadLocal作为解决方法

static ThreadLocal<SimpleDateFormat> format1 = new ThreadLocal<SimpleDateFormat>() {
    @Override
    protected SimpleDateFormat initialValue() {
        return new SimpleDateFormat("yyyy-MM-dd");
    }
};

public String formatDate(Date date) {
    return format1.get().format(date);
}
static ThreadLocal format1=new ThreadLocal(){
@凌驾
受保护的SimpleDataFormat初始值(){
返回新的SimpleDataFormat(“yyyy-MM-dd”);
}
};
公共字符串格式日期(日期){
返回format1.get().format(日期);
}

Java中的ThreadLocal是一种实现线程安全的方法,除了编写不可变的类之外。由于SimpleDataFormat不是线程安全的,因此可以使用ThreadLocal使其成为线程安全的

class DateFormatter{

    private static ThreadLocal<SimpleDateFormat> outDateFormatHolder = new ThreadLocal<SimpleDateFormat>() {
    @Override
    protected SimpleDateFormat initialValue() {
        return new SimpleDateFormat("MM/dd/yyyy");
    }
};

private static ThreadLocal<SimpleDateFormat> inDateFormatHolder = new ThreadLocal<SimpleDateFormat>() {
    @Override
    protected SimpleDateFormat initialValue() {
        return new SimpleDateFormat("yyyyMMdd");
    }
};

public static String formatDate(String date) throws ParseException { 
    return outDateFormatHolder.get().format(
            inDateFormatHolder.get().parse(date));
}        
}
类日期格式化程序{
私有静态ThreadLocal outDateFormatHolder=new ThreadLocal(){
@凌驾
受保护的SimpleDataFormat初始值(){
返回新的SimpleDataFormat(“MM/dd/yyyy”);
}
};
私有静态ThreadLocal inDateFormatHolder=新ThreadLocal(){
@凌驾
受保护的SimpleDataFormat初始值(){
返回新的SimpleDataFormat(“yyyyMMdd”);
}
};
公共静态字符串formatDate(字符串日期)引发语法异常{
返回outDateFormatHolder.get().format(
inDateFormatHolder.get().parse(date));
}        
}

为什么需要使用ThreadLocal?因为SimpleDataFormat(以及大多数其他格式实例)不是线程安全的。关于这个话题,请看我的文章。人们会这样做吗?如果你(原来的l海报)没有正确理解ThreadLocals,我建议你不要使用它们。我可能会考虑FastDateFormat从JoalTiMe库中从Calm Langor或DATETMEMEDATE格式。这是一条关于这个问题的长而有趣的线索@约翰马克13:是的,人们都这么做。我也喜欢它。他怎么会不理解呢?《高效Java》一书的作者Joshua Bloch在你的链接上说:“这个线程充满了错误信息。[..]线程局部变量本身并没有什么问题:它们不会导致内存泄漏,也不会太慢。”。讨论的是Tomcat和其他一些应用程序中的bug,这些应用程序使用线程池,并且在ThreadLocals中存在实现问题。它们可以而且应该在这些应用程序中修复。@StijndeWitt,因为他的问题是[转述]“我不知道如何使用本地线程进行修复”。另请参见“否则它将泄漏内存。为什么在当前线程工作完成后我们还需要这些引用”,这表明缺乏理解。“同意”应该固定在容器中,但您首先需要了解它们是什么,其次,如果您不正确地使用它们,它们可能会对您的项目产生什么影响。或者,只需从SO复制一段代码片段,不必担心理解它的功能。是的。。。我对这个答案的评论感到困惑,而不是问题本身,但你是对的。。。只有当你理解它的效果时才使用它。谢谢Richie,但是你的类没有工作,比如说类主体,字段声明没有完成。我添加了额外的右括号,但仍然没有运气。还有如何在调用结束后删除这些threadlocal引用。现在检查。我现在已经添加了大括号。否则它会泄漏内存。为什么我们要在当前线程工作完成后使用这些引用。如果您看到代码-两个对象都是静态的,这意味着它将类似于singleton。只要不是每次都创建ThreadLocal实例,就不必担心内存泄漏。但如果您非常特别—要删除引用,可以从formatDate方法手动调用outDateFormatHolder.remove()和inDateFormatHolder.remove()。“最终日期日期=format1.parse(tradeDate);最终日期formattedDate=format2.parse(format2.format(Date));”-日期和formattedDate相同-您可以调试和检查。如果您需要date对象,那么第一条语句就足够了—date对象没有以该格式存储。如果要在第二次声明后再次打印日期对象,仍然需要调用format方法。