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(); } }