今天有同事说SimpleDateFormat不是线程安全的,于是我做了试验
1 public class TestSimpleDateFormat 2 { 3 final static SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd"); 4 5 public static void main(String[] args) { 6 7 int NUMBER_OF_THREADS = 1000; 8 9 for( int i = 0; i < NUMBER_OF_THREADS ; i++ ) { 10 TimeCalc tc = new TimeCalc("20151212",i); 11 tc.start(); 12 } 13 } 14 15 static class TimeCalc extends Thread { 16 private String date; 17 public String getDate() { 18 return date; 19 } 20 public TimeCalc(String date, int index) { 21 this.date = date; 22 } 23 24 @Override 25 public void run() { 26 27 try { 28 29 Date parsedDate = null; 30 // synchronized(sdf) { 31 parsedDate = sdf.parse(date); 32 // } 33 System.out.println(parsedDate); 34 } catch (ParseException e) { 35 e.printStackTrace(); 36 } catch (Exception e) { 37 e.printStackTrace(); 38 } 39 } 40 41 } 42 }
我会收到下面如下两种异常,
去掉30行和32行的注释,一切运行正常。
另外,我也试过org.apache.commons.lang3.time.FastDateParser,这个类也是线程安全的。不过这个类没有public的构造器和静态的工厂方法,只有一个protected的构造函数,看来唯一使用它的方法就是自己动手做一个它的子类,然后给出静态的工厂方法。经测试,在多线程下,没有错误。
1 static class MyDateParser extends FastDateParser { 2 3 protected MyDateParser(String arg0, TimeZone arg1, Locale arg2, 4 Date arg3) { 5 super(arg0, arg1, arg2, arg3); 6 } 7 8 public static MyDateParser getDateParser( String pattern ) { 9 return new MyDateParser(pattern, TimeZone.getDefault(), Locale.getDefault(), null); 10 } 11 12 }
在网上搜索了,还有更好方法,用Joda Time,如果你在用Java 8,java.time下的类应该都是来自于Joda Time。
原文:http://www.cnblogs.com/shengyang/p/4649561.html