轉:simpledateformat 線程不安全

如果一個資源或對象可能被多個線程同時訪問,它就是一個共享資源;例如類的成員變量,包括類變量和實例變量,再比如對一個文件進行寫操作等。一般情況下,對共享資源的訪問需要考慮線程安全的問題。

  如果一個對象的完整生命週期只在一個線程內,則不需要考慮線程安全,例如一個局部變量。下面爲一個示例代碼:

public class C1 { 

public static java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd"); 

//其他代碼 

} 

 

  假如在一個JSP中這樣的去調用:

<a.jsp>: 

<% 

Java.util.Date date = C1.sdf.parse(“2003-4-15”); 

%> 

 

  則這樣的代碼不是線程安全的。因爲java.text.SimpleDateFormat不是線程安全的,a.jsp中的代碼將會有若干個線程同時執行,而都訪問的是同一個線程不安全的對象,這樣就不是一個線程安全的代碼。正確的寫法應該如下:

<a.jsp>: 

<% 

java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd"); 

Java.util.Date date = sdf.parse(“2003-4-15”); 

%> 

 

2、 原因分析:

  此時,sdf對象從創建到銷燬都位於一個方法中,相當於一個局部變量,不是一個共享資源,因此則沒有線程不安全的問題。

3、 解決方法或過程:

1) 如果對象是immutable,則是線程安全的,例如:String,可以放心使用。
2) 如果對象是線程安全的,則放心使用
3) 有條件線程安全,對於Vector和Hashtable一般情況下是線程安全的,但是對於某些特殊情況,需要通過額外的synchronized保證線程安全。
4) 使用synchronized關鍵字;

  對於上例中可以改寫jsp代碼,在sdf上進行同步,而不需要每次創建一個新的對象來保證線程安全,代碼如下:

<% 

synchronized(C1.sdf){ 

Java.util.Date date = C1.sdf.parse(“2003-4-15”); 

} 

%> 

 

  這種寫法是在一個對象級別上進行同步,也就是說任何時候,對於這個對象,最多只能有一個線程在執行同步方法。

  另外一種寫法是在Class級別上進行同步,寫法如下:

public class C1 { 

public static java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd"); 



public void method(){ 

synchronized(C1.class){ 

//synchronized code 

} 

} 

} 

 

  這種寫法表示無論C1有多少個實例,在任何一個時間點,最多只能有一個線程和一個實例進入同步塊中。這種同步會比較大的影響性能。

  5) 有些對象不能在多線程間共享,則只能在方法內部使用,或者只在一個線程內部使用。

發佈了45 篇原創文章 · 獲贊 0 · 訪問量 1464
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章