证明SimpleDateFormat不是线程安全的 [英] Proving that SimpleDateFormat is not threadsafe

查看:106
本文介绍了证明SimpleDateFormat不是线程安全的的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想通过简单的JUnit测试向同事表明SimpleDateFormat是不是线程安全的.以下类无法说明我的意思(在多线程环境中重用SimpleDateFormat),我也不明白为什么.您能找到阻止我使用SDF引发运行时异常的原因吗?

I want to show to a colleague that SimpleDateFormat is not thread-safe through a simple JUnit test. The following class fails to make my point (reusing SimpleDateFormat in a multi-threaded environment) and I don't understand why. Can you spot what is preventing my use of SDF from throwing a runtime exception?

public class SimpleDateFormatThreadTest
{
    @Test
    public void test_SimpleDateFormat_MultiThreaded() throws ParseException{
        Date aDate = (new SimpleDateFormat("dd/MM/yyyy").parse("31/12/1999"));
        DataFormatter callable = new DataFormatter(aDate);

        ExecutorService executor = Executors.newFixedThreadPool(1000);
        Collection<DataFormatter> callables = Collections.nCopies(1000, callable);

        try{
            List<Future<String>> futures = executor.invokeAll(callables);
            for (Future f : futures){
                try{
                    assertEquals("31/12/1999", (String) f.get());
                }
                catch (ExecutionException e){
                    e.printStackTrace();
                }
            }
        }
        catch (InterruptedException e){
            e.printStackTrace();
        }
    }
}

class DataFormatter implements Callable<String>{
    static SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");

    Date date;

    DataFormatter(Date date){
        this.date = date;
    }

    @Override
    public String call() throws RuntimeException{
        try{
            return sdf.format(date);
        }
        catch (RuntimeException e){
            e.printStackTrace();
            return "EXCEPTION";
        }
    }
}

推荐答案

缺乏线程安全性并不一定意味着代码将引发异常.尝试浏览Andy Grove的文章: SimpleDateFormat和线程安全;他通过显示在给定不同输入的情况下输出并非总是正确的来表明其缺乏线程安全性.

Lack of thread safety doesn't necessarily mean that the code will throw an exception. Try looking through Andy Grove's article: SimpleDateFormat and Thread Safety; he showed its lack of thread safety by showing that the output would not always be correct, given different inputs.

运行此代码时,得到以下输出:

When I run this code, I get the following output:

java.lang.RuntimeException: date conversion failed after 3 iterations.
Expected 14-Feb-2001 but got 01-Dec-2007

请注意,"2007年12月1日"甚至不是测试数据中的字符串之一.它实际上是其他两个线程正在处理的日期的组合!

Note that "01-Dec-2007" isn't even one of the strings in the test data. It is actually a combination of the dates being processed by the other two threads!

这篇关于证明SimpleDateFormat不是线程安全的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆