【问题标题】:ThreadLocal for multithreaded access to SimpleDateFormatThreadLocal 用于多线程访问 SimpleDateFormat
【发布时间】:2012-05-08 00:57:48
【问题描述】:

我有许多 Java 日期模式,并希望通过静态引用在不同线程中的 SimpleDateFormat 对象中多次重用它们,以提高速度。

代码看起来像这样(在一个名为 FormatClass 的类中):

private static String[] PATTERNS = new String[] {...};

public 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[0]);
    }
}

使用上面的代码,另一个类的方法可以format(或parse)多个日期字符串如下:

public static void printFormatted(String date)
{
    for (SimpleDateFormat sdf:FormatClass.LOCAL_FORMATS.get())
    {
        System.out.println(sdf.format(date));
    }
}

printFormatted() 方法可能是静态的,也可能不是静态的,但肯定会被多个不同的线程访问。

上述方法会按预期工作吗?

【问题讨论】:

  • 使用toArray方法时,使用new SimpleDateFormat[list.size()]效率更高。
  • 不,如果你看toArray()方法的源码,是一模一样的。
  • 阅读我给你的链接。不完全相同,如果您提供的数组最初足够大以包含整个列表,它将使用该数组。如果不这样做,它将必须分配一个全新的数组并将其转换为正确的类型。
  • 另见stackoverflow.com/questions/11376328/…,这是关于该问题的一个较新的问题,它阐明了对 SimpleDateFormat[] 数组的引用应始终通过 LOCAL_FORMATS.get() 获得,而不是在 public变量到 LOCAL_FORMATS.get() 然后使用该变量来引用数组;在后一种情况下,所有线程都访问数组的同一个副本,这显然不是线程安全的。

标签: java thread-safety simpledateformat thread-local


【解决方案1】:

直接回答您的问题:是的,每个线程都会有自己独特的副本,如 SimpleDateFormat 文档中所建议的那样。

【讨论】:

  • 你的意思是我发布的代码将实现这一点,是吗?我知道文档,因此使用 ThreadLocal。
  • 是的,有了这段代码,每个线程都可以安全地使用这些 SimpleDateFormat,因为每个请求它的线程都会有一个唯一的 SimpleDateFormat 数组,所以如果你有很多线程,请小心.
【解决方案2】:

它看起来不错,但是您可以使用多线程程序轻松测试它。只需打印线程的 ID (Thread.currentThread().toString()) 和 System.identifyHashCode(simpleDateFormat) 并验证您是否获得了每个线程的唯一副本并适当地重用它们。

【讨论】:

    【解决方案3】:

    这很好用,但代码相对复杂。我建议检查一下您是否可以将 SimpleDateFormat 分配给方法内的某个局部变量(始终是线程本地的)。当许多值在一个循环中格式化,然后可以在同一个方法中时,这很有效。

    【讨论】:

      【解决方案4】:

      我认为还有一种更优雅的方法,目前还没有人提出过——只需为 SimpleDateFormat 创建一个替换包装类,以同步对其方法的访问。在大多数情况下,我认为同步开销并不比 ThreadLocalMap 中的哈希查找差。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-07-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多