2011-2-17 不安全的多线程
在我们的代码的里面经常有这样的例子,为了格式化日期(如:2011-02-17), 就需要一个SimpleDateFormat类,同时,为了让整个系统共享这个格式化类,我们把这个格式化类写到一个公共的Util类里面,代码如下:
Util 类:
原因在于:
如果是单线程,使用这个Util类是没有问题的;
如果是多线程的话,就会产生并发访问同一个实例化的SimpleDateFormat类。
JDK API中声明DateFormat类和SimpleDateFormat类都不是线程同步的,推荐对于每个线程创建一个实例。如果多线程访问的话,自己实现多线程同步;
1: 最简单的方法是在每次使用的时候,new一个新的DateFormat;效率稍许损失,不能达到系统共享同一个格式化类。最简单的编程模型。推荐。
2: 增加线程同步访问: 但是多线程的效率将损失,并且容易导致死锁。private static final Map<Long, DateFormat> DateFormaterMap = new HashMap<Long, DateFormat>();// return date formater by thread Idpublic static DateFormat getDateFormaterByThread() {Long tId = Thread.currentThread().getId();if (Util.DateFormaterMap.containsKey(tId)) {return Util.DateFormaterMap.get(tId);} else {// another strategy: use SimpleDateFormat's clone method with a default oneSimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");Util.DateFormaterMap.put(tId, sdf);return sdf;}}
建议在写单元测试的时候,增加一项多线程测试。