有一個網友在高並發下使用下面的日期轉換工具類時,遇到的問題
public class DateUtil
{
private DateUtil(){
}
private static final DateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
public static Date parse(String date) throws ParseException
{
return DATE_FORMAT.parse(date);
}
}
異常:
java.lang.NumberFormatException: For input string: ""
SimpleDateFormat這個類的源碼。果然,在這個類的注釋里,有這么一段話。
* Date formats are not synchronized. * It is recommended to create separate format instances for each thread. * If multiple threads access a format concurrently, it must be synchronized * externally.
如何對待和定義靜態對象?
static的目的是class共有的,並在內存中只定義一份,降低對內存的消耗,但在高並發下,要注意這種共享資源的安全問題。
觀點:
static破壞了封閉,所有的類共享一個實例,在高並發第一個出問題必定是static,去掉static 可能一點事都沒有
無論在java,還是在c++,還是objective-c,盡量少用static,特別在有多線程的場合
static表面上省內存,實質上更占內存,因為static內存很多時候不會被及時釋放,static可能會導致性能降低,因為多個類都在等static的資源,static可能會導致並發問題。
oop的原則是能用new object就用new object,盡量不要在oop的牆上打洞。
觀點二:
static是定時炸彈,不知道什么時候發作。不去使用它就不會發作。有了new根本沒必要使用static,static反而會使內存出現問題,而new的問題比較容易解決。
static是c語言時代的產生,是為了方便共享資源,大凡“共享”的東西都容易出問題,因為“共享”的東西會出出現資源競爭的情況,在一定條件下就會發作。
現代cpu算力過剩,但內存不能崩,所以根本不需要使用static。
static是兼容所謂c++設計的,用於學習測試等單線程環境使用,是歷史問題,在生產中中盡量不要使用static,使用new object才能充分發揮oop在jvm上的安全和自動管理性能。