【Java线程】SimpleDateFormat的线程安全性实验
【代码】
package unsafesdf; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Collections; import java.util.HashSet; import java.util.Set; import java.util.concurrent.CountDownLatch; import java.util.concurrent.Executor; import java.util.concurrent.Executors; public class Test { private static SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd"); private static final int COUNT=100; private static final Executor exec=Executors.newFixedThreadPool(COUNT); public static void main(String[] args) throws Exception{ Set<String> set=Collections.synchronizedSet(new HashSet<String>()); CountDownLatch cdl=new CountDownLatch(COUNT); for(int i=0;i<COUNT;i++) { Calendar clder=Calendar.getInstance(); final int ct=i; exec.execute(()->{ clder.add(Calendar.DATE, ct); String dateStr=sdf.format(clder.getTime()); set.add(dateStr); cdl.countDown(); }); } cdl.await(); // 预期100,但实际小于100 System.out.println(set.size()); } }
【五次输出】
71
61
65
78
74
【原因】
SimpleDateFormat内部使用一个canlendat保存输入的时间,这在多线程环境里容易被后入线程所改写。
【参考资料】
《深入Java核心技术》张宏亮著 P390~391.
END
浙公网安备 33010602011771号