ThreadLocal 和 SimpleDateFormat 数组 [英] ThreadLocal and SimpleDateFormat array

查看:36
本文介绍了ThreadLocal 和 SimpleDateFormat 数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用与最近的问题中描述的模式非常相似的模式,对于多线程应用程序,我得到了奇怪的日期值(例如,像 2025 或 2035 这样的年份,显然源数据中不存在这样的值).似乎发生了并发问题.

Using a pattern very similar to that described in a recent question, for a multithreaded application, I am getting weird date values (e.g., years like 2025 or 2035, when clearly no such value exists in the source data). It seems that a concurrency issue is occuring.

源代码看起来像

// Various Java DateFormat patterns, e.g. "yyyy-MM-dd".
private static final String[] DATE_PATTERNS = new String[] {...};

private static SimpleDateFormat[] getFormats(final String[] patterns)
{
    ThreadLocal<SimpleDateFormat[]> LOCAL_FORMATS = new ThreadLocal<SimpleDateFormat[]>()
    {
        @Override
        protected SimpleDateFormat[] initialValue()
        {
            List<SimpleDateFormat> formatList = new ArrayList<SimpleDateFormat>();

            for (String pattern:patterns)
            {
                formatList.add(new SimpleDateFormat(pattern));
            }

            return formatList.toArray(new SimpleDateFormat[formatList.size()]);
        }
    };

    return LOCAL_FORMATS.get(); // Create a thread-local copy
}

private static final SimpleDateFormat[] DATE_FORMATS = getFormats(DATE_PATTERNS);

在静态初始化之后,DATE_FORMATS 数组被许多类访问,这些类又使用数组的 SimpleDateFormat 对象来解析或格式化多个日期字符串.

After its static initialization, the DATE_FORMATS array is accessed by numerous classes, which in turn use the SimpleDateFormat objects of the array for parsing or formatting several date strings.

在这样的使用场景下会不会有并发问题,尤其是在使用ThreadLocal的情况下?

Can there be any concurrency issue in such a usage scenario, especially given the use of ThreadLocal?

推荐答案

是的,可能存在并发问题.您的线程局部变量没有任何用途.它仅在类初始化时使用,以临时存储可立即检索并存储在静态常量中的日期格式数组.

Yes, there can be concurrency issues. Your thread local variable doesn't serve any purpose. It's only used when the class is initialized, to temporarily store an array of date formats that is immediately retrieved and stored in a static constant.

之后,所有线程始终同时使用相同的日期格式实例,而不从任何线程局部变量中获取它们.

All the threads, after, always use the same instances of date formats concurrently, without getting them from any thread local variable.

代码应该是:

private static final String[] DATE_PATTERNS = new String[] {...};
private static final ThreadLocal<SimpleDateFormat[]> DATE_FORMATS = 
    new ThreadLocal<SimpleDateFormat[]>() {
        @Override
        protected SimpleDateFormat[] initialValue() {
            List<SimpleDateFormat> formatList = new ArrayList<SimpleDateFormat>();

            for (String pattern : DATE_PATTERNS)
            {
                formatList.add(new SimpleDateFormat(pattern));
            }

            return formatList.toArray(new SimpleDateFormat[formatList.size()]);
        }
    };

public static SimpleDateFormat[] getDateFormats() {
    return DATE_FORMATS.get();
}

为了更安全,我还会使用不可修改的 List 而不是数组.

I would also use an unmodifiable List<SimpleDateFormat> rather than an array, to be safer.

这篇关于ThreadLocal 和 SimpleDateFormat 数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆