java - 多个线程使用相同的SimpleDateFormat而不使用ThreadLocal

标签 java multithreading thread-local

我试图理解使用ThreadLocal的需要。很多人提到 ThreadLocal 应该用于提供每线程 SimpleDateFormat,但他们没有提到如何看到损坏的 SimpleDateFormat如果未使用 ThreadLocal。我尝试了以下代码,似乎很好,我没有看到损坏的 SimpleDateFormat

import java.text.SimpleDateFormat;
import java.util.Date;

public class ThreadLocalTest {
  private static final SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
  private static final Date TODAY = new Date();
  private static final String expected = "07/09/2016";
  public static void main(String[] args) {
    for (int i = 0; i < 10000; i++) {
      new Thread(new Runnable() {
        @Override
        public void run() {
          for (int j = 0; j < 1000; j++) {
            String real = dateFormat.format(TODAY);
            if (!real.equals(expected)) {
              throw new RuntimeException("Mangled SimpleDateFormat");
            }
          }
        }
      }).start();
    }
  }
}

由于我不使用 ThreadLocal,如何产生类似 NumberFormatException 的异常?

最佳答案

关键点是:SimpleDateFormat 实现不是线程安全。

这并不意味着它会抛出异常。 它更糟:也许共享格式化程序偶尔会给你错误的输出!

你知道,如果“多线程问题”能够很好地向你抛出异常……人们就不会那么害怕它们了。因为我们会得到一个直接的暗示,表明出现了问题。

相反,事情会出错 - 并且未被注意到

建议:增强您的测试

  1. 始终设置相同日期对象的格式
  2. 检查格式化日期的结果是否符合预期(例如,将其与初始的第一次格式化操作的结果进行比较)

当然:只打印不匹配的情况,以便在它们发生时注意到。或者更好:在不匹配时抛出您自己的异常!

编辑:事实证明,强制不一致的“更好”方法是不使用格式化,而是解析!

最后,要解决另一个问题:当然,只有在多个线程之间共享的对象才会出现不一致。当每个线程都有自己的格式对象时,就没有共享;因此没问题。

关于java - 多个线程使用相同的SimpleDateFormat而不使用ThreadLocal,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39363434/

相关文章:

c# - SynchronizationContext.Current 在主线程上为空

c++ - C++ 是否提供内置的多线程支持?

multithreading - 线程本地,类实例本地存储?

java - 如何为声明为 ThreadLocal 的变量的多个副本保持一致性?

java - 第二次访问时为空数据

java - 尝试使用 Spring Config Server 时如何修复 "There are not any available ciphers"JSch 异常?

java - 扫描外部主机端口

c++ - 如何让协程始终在同一个线程中工作?

java - 为每个线程获取该程序的输出 null

java - 用java修改xml版本