类型: 质量问题

    格式化对象是非线程安全的,java.text.Format中的parse()和format()方法包含一个可导致用户看到其他用户数据的race condition。

    1. public class DateFormat extends Thread{
    2. private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    3. private String name;
    4. private String dateStr;
    5. public DateFormat(String name, String dateStr) {
    6. this.name = name;
    7. this.dateStr = dateStr;
    8. }
    9. @Override
    10. public void run() {
    11. try {
    12. Date date = sdf.parse(dateStr);
    13. System.out.println("线程"+name+"运行日期:"+date);
    14. } catch (ParseException e) {
    15. e.printStackTrace();
    16. }
    17. }
    18. public static void main(String[] args) {
    19. ExecutorService executorService = Executors.newFixedThreadPool(3);
    20. executorService.execute(new DateFormat("A", "2017-06-10"));
    21. executorService.execute(new DateFormat("B", "2016-06-06"));
    22. executorService.shutdown();
    23. }
    24. }

    如上代码中输出会有两种情况,一种情况是报错,还有一种情况是两个线程输出一致。出现这种情况的原因是因为SimpleDateFormat类内部有一个Calendar对象引用,它用来储存和这个SimpleDateFormat相关的日期信息。这样就会导致一个问题,如果SimpleDateFormat是static的, 那么多个thread之间就会共享SimpleDateFormat, 同时也是共享Calendar引用。在高并发的情况下,容易出现幻读成员变量的现象。