Java8新增的DateTimeFormatter與SimpleDateFormat的區別

二者最大的區別是,Java8的DateTimeFormatter也是線程安全的,而SimpleDateFormat並非線程安全。java

在併發環境下使用SimpleDateFormat安全

爲了可以在多線程環境下使用SimpleDateFormat,有這三種方法:多線程

方法一併發

在須要執行格式化的地方都新建SimpleDateFormat實例,使用局部變量來存放SimpleDateFormat實例ide

public static String formatDate(Date date) throws ParseException { 
	SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 
	return sdf.format(date); 
}

這種方法可能會致使短時間內建立大量的SimpleDateFormat實例,如解析一個excel表格裏的字符串日期。高併發

方法二spa

爲了不建立大量的SimpleDateFormat實例,每每會考慮把SimpleDateFormat實例設爲靜態成員變量,共享SimpleDateFormat對象。這種狀況下就得對SimpleDateFormat添加同步。線程

private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 

public static String formatDate(Date date) throws ParseException { 
	synchronized(sdf) { 
		return sdf.format(date); 
	} 
}

這種方法的缺點也很明顯,就是在高併發的環境下會致使解析被阻塞。excel

方法三(推薦)code

要在高併發環境下能有比較好的體驗,能夠使用ThreadLocal來限制SimpleDateFormat只能在線程內共享,這樣就避免了多線程致使的線程安全問題。

private static ThreadLocal<DateFormat> threadLocal = new ThreadLocal<DateFormat>() { 
	@Override 
	protected DateFormat initialValue() { 
		return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 
	} 
};

public static String format(Date date) { 
	return threadLocal.get().format(date); 
}

DateTimeFormatter使用

解析日期

String dateStr= "2016年10月25日"; 
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日");   
LocalDate date= LocalDate.parse(dateStr, formatter);

日期轉換爲字符串

LocalDateTime now = LocalDateTime.now(); 
DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyy年MM月dd日 hh:mm a"); 
String nowStr = now .format(format);

由DateTimeFormatter的靜態方法ofPattern()構建日期格式,LocalDateTime和LocalDate等一些表示日期或時間的類使用parse和format方法把日期和字符串作轉換。

使用新的API,整個轉換過程都不須要考慮線程安全的問題。

相關文章
相關標籤/搜索