证明SimpleDateFormat不是线程安全的

Pom*_*rio 4 java multithreading

我想向同事展示SimpleDateFormat 通过简单的JUnit测试不是线程安全的.下面的类没有说明我的观点(在多线程环境中重用SimpleDateFormat),我不明白为什么.你能发现什么阻止我使用SDF抛出运行时异常吗?

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";
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Cla*_*diu 11

缺乏线程安全并不一定意味着代码会抛出异常.试着看看Andy Grove的文章:SimpleDateFormat和Thread Safety ; 由于输入不同,他表明输出并不总是正确的,因此表明它缺乏线程安全性.

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

java.lang.RuntimeException: date conversion failed after 3 iterations.
Expected 14-Feb-2001 but got 01-Dec-2007
Run Code Online (Sandbox Code Playgroud)

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