【问题标题】:SimpleDateFormat ThreadSafe Suggestion-> creating new object is better or ThreadLocal is?SimpleDateFormat ThreadSafe Suggestion-> 创建新对象更好还是 ThreadLocal 更好?
【发布时间】:2014-10-09 06:48:34
【问题描述】:

我正在构建一个应用程序,我必须在其中格式化日期。对于格式化,我正在使用

SimpleDateFormatter class.

据我所知,有三种方法可以通过同步来使用这个类

1) 使用

创建局部变量
 new SimpleDateFormatter("MM/dd/yyyy")

2) 使用同步关键字

synchronized(this) {
      simpleDateFormatter.format(date); //use static object and then format with synchronization
}

3) 像这样使用带有简单日期格式化程序的线程局部变量

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

我正在构建 Web 应用程序,我可以在其中接收多个请求,并且在某些时候我将格式化日期。

现在我知道,如果我必须在同一个线程中多次格式化,那么 ThreadLocal 会是更好的选择。

但根据当前情况,每个线程都会格式化一次日期。

问题-> 整个问题归结为情况。什么是更好的选项 1 或 3,因为选项 2 会有性能问题。

因为我只需要格式化一次,

---------> 选项 1 和选项 3 相同吗?如果不是,我的情况下哪个更好?

-----> 有没有其他方法可以使它成为线程安全的,不会出现性能或内存问题(在 ThreadLocal 的情况下读取)。

我愿意接受建议。请分享您的意见。

感谢您的宝贵时间。

【问题讨论】:

  • 另一种方法是使用 Apache Commons Lang 的 FastDateFormat 类,它是 SimpleDateFormatter 的线程安全版本。
  • 谢谢,我想这是一个更好的选择。
  • 保持简单,只需在需要时创建一个新实例。我怀疑这会导致任何性能问题。
  • 我必须每秒处理大约 10,000 个请求。由于 SimpleDateFormatter 的对象创建不是那么轻,它肯定会对性能产生影响
  • @ParasMittal 我会鼓励一种比这更轻松的方法。请记住前两个优化规则。只需编写程序的其余部分,并且仅当生成的应用程序太慢时并且您以后可以确定这部分代码是最慢的,然后再考虑一下。

标签: java multithreading simpledateformat thread-local


【解决方案1】:

如果你的情况是单线程只需要格式化一次日期,那么使用 ThreadLocal 没有意义,你可以简单地每次创建新对象。

由于对象仍在创建这种情况,在这种情况下使用 ThreadLocal 的成本会很高,并且可能会出现内存问题。我的建议 -> 去创建新的对象。

我认为您对同步的看法是正确的,因为它会阻塞线程,而且您必须处理每秒大约 10,000 个这样的大请求。

另一个选择是使用@Duncan 建议的 Apache Commons Lang 的 FastDateFormat 类。

希望这是您正在寻找的答案...

【讨论】:

  • 谢谢@Atul Sharma,这就是我一直在寻找的。​​span>
  • +1 或者您可以使用 JSR-310 反向端口,因为 JSR-310 基于 Joda Time,是 Java 8 中的首选选项。
【解决方案2】:

SimpleDateFormatter 是一个相当轻量级的结构。根据 SimpleDateFormatter 上用于解析和格式化的调用量,如果您使用同步并共享单个实例,您最终会在那里遇到大量阻塞线程。

创建一个新实例并在需要时使用它会更好、更容易。

【讨论】:

  • 我实际上在 ThreadLocal 和每次都创建新实例之间感到困惑。我知道使用同步关键字肯定会出现性能问题。
  • ThreadLocal 会为每个进入的线程保留一份 SimpleDateFormatter 的副本。但是 ThreadLocal 非常危险,因为它可能导致内存泄漏。阅读walivi.wordpress.com/2013/08/24/… 的“线程限制 – 线程本地副本”部分,它解释了潜在的问题和应该使用它的场景。
猜你喜欢
  • 2017-03-23
  • 2019-04-12
  • 2015-07-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-22
  • 2019-06-24
  • 1970-01-01
相关资源
最近更新 更多