Java多線程編程中應用DateFormat類。本站提示廣大學習愛好者:(Java多線程編程中應用DateFormat類)文章只能為提供參考,不一定能成為您想要的結果。以下是Java多線程編程中應用DateFormat類正文
DateFormat 類是一個非線程平安的類。javadocs 文檔外面提到"Date formats是不克不及同步的。 我們建議為每一個線程創立自力的日期格局。 假如多個線程同時拜訪一個日期格局,這須要在內部加上同步代碼塊。"
以下的代碼為我們展現了若何在一個線程情況外面應用DateFormat把字符串日期轉換為日期對象。創立一個實例來獲得日期格局會比擬高效,由於體系不須要屢次獲得當地說話和國度。
public class DateFormatTest {
private final DateFormat format =
new SimpleDateFormat("yyyyMMdd");
public Date convert(String source)
throws ParseException{
Date d = format.parse(source);
return d;
}
}
這段代碼長短線程平安的。我們可以經由過程在多個線程中挪用它。在以下挪用的代碼中,我創立了一個有兩個線程的線程池,並提交了5個日期轉換義務,以後檢查運轉成果:
final DateFormatTest t =new DateFormatTest();
Callable<Date> task =new Callable<Date>(){
public Date call()throws Exception {
return t.convert("20100811");
}
};
//讓我們測驗考試2個線程的情形
ExecutorService exec = Executors.newFixedThreadPool(2);
List<Future<Date>> results =
new ArrayList<Future<Date>>();
//完成5第二天期轉換
for(int i =0; i <5; i++){
results.add(exec.submit(task));
}
exec.shutdown();
//檢查成果
for(Future<Date> result : results){
System.out.println(result.get());
}
代碼的運轉成果並不是如我們所願 - 有時刻,它輸入准確的日期,有時刻會輸入毛病的(例如.Sat Jul 31 00:00:00 BST 2012),有些時刻乃至會拋出NumberFormatException!
若何並發應用DateFormat類
我們可以有多種辦法在線程平安的情形下應用DateFormat類。
1. 同步
最簡略的辦法就是在做日期轉換之前,為DateFormat對象加鎖。這類辦法使得一次只能讓一個線程拜訪DateFormat對象,而其他線程只能期待。
public Date convert(String source)
throws ParseException{
synchronized(format) {
Date d = format.parse(source);
return d;
}
}
2. 應用ThreadLocal
別的一個辦法就是應用ThreadLocal變量去包容DateFormat對象,也就是說每一個線程都有一個屬於本身的正本,並沒有需期待其他線程去釋放它。這類辦法會比應用同步塊更高效。
public class DateFormatTest {
private static final ThreadLocal<DateFormat> df
= new ThreadLocal<DateFormat>(){
@Override
protected DateFormat initialValue() {
return new SimpleDateFormat("yyyyMMdd");
}
};
public Date convert(String source)
throws ParseException{
Date d = df.get().parse(source);
return d;
}
}
3. Joda-Time
Joda-Time 是一個很棒的開源的 JDK 的日期和日歷 API 的替換品,其 DateTimeFormat 是線程平安並且不變的。
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import java.util.Date;
public class DateFormatTest {
private final DateTimeFormatter fmt =
DateTimeFormat.forPattern("yyyyMMdd");
public Date convert(String source){
DateTime d = fmt.parseDateTime(source);
returnd.toDate();
}
}