我试图理解使用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 实现不是线程安全。
这并不意味着它会抛出异常。 它更糟:也许共享格式化程序偶尔会给你错误的输出!
你知道,如果“多线程问题”能够很好地向你抛出异常……人们就不会那么害怕它们了。因为我们会得到一个直接的暗示,表明出现了问题。
相反,事情会出错 - 并且未被注意到。
建议:增强您的测试
- 始终设置相同日期对象的格式
- 检查格式化日期的结果是否符合预期(例如,将其与初始的第一次格式化操作的结果进行比较)
当然:只打印不匹配的情况,以便在它们发生时注意到。或者更好:在不匹配时抛出您自己的异常!
编辑:事实证明,强制不一致的“更好”方法是不使用格式化,而是解析!
最后,要解决另一个问题:当然,只有在多个线程之间共享的对象才会出现不一致。当每个线程都有自己的格式对象时,就没有共享;因此没问题。
关于java - 多个线程使用相同的SimpleDateFormat而不使用ThreadLocal,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39363434/