3

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

源代码看起来像

// 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数组的对象来解析或格式化多个日期字符串。

在这种使用场景中是否存在任何并发问题,尤其是考虑到使用ThreadLocal?

4

2 回答 2

4

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

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

代码应该是:

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<SimpleDateFormat>而不是数组。

于 2012-07-07T16:03:49.257 回答
2
// Various Java DateFormat patterns, e.g. "yyyy-mm-dd".

'yyyy-mm-dd' 格式可能会给您带来奇怪的结果,因为 'mm' 是分钟而不是月。从javadoc:

M   Month in year   Month   July; Jul; 07
...
m   Minute in hour  Number  30
于 2012-07-07T15:56:43.563 回答