类型: 质量问题
格式化对象是非线程安全的,java.text.Format中的parse()和format()方法包含一个可导致用户看到其他用户数据的race condition。
public class DateFormat extends Thread{private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");private String name;private String dateStr;public DateFormat(String name, String dateStr) {this.name = name;this.dateStr = dateStr;}@Overridepublic void run() {try {Date date = sdf.parse(dateStr);System.out.println("线程"+name+"运行日期:"+date);} catch (ParseException e) {e.printStackTrace();}}public static void main(String[] args) {ExecutorService executorService = Executors.newFixedThreadPool(3);executorService.execute(new DateFormat("A", "2017-06-10"));executorService.execute(new DateFormat("B", "2016-06-06"));executorService.shutdown();}}
如上代码中输出会有两种情况,一种情况是报错,还有一种情况是两个线程输出一致。出现这种情况的原因是因为SimpleDateFormat类内部有一个Calendar对象引用,它用来储存和这个SimpleDateFormat相关的日期信息。这样就会导致一个问题,如果SimpleDateFormat是static的, 那么多个thread之间就会共享SimpleDateFormat, 同时也是共享Calendar引用。在高并发的情况下,容易出现幻读成员变量的现象。
