dateformat线程_Java最佳实践–多线程环境中的DateFormat
dateformat線程
這是有關使用Java編程語言時的擬議實踐的系列文章的第一篇。
所有討論的主題均基于用例,這些用例源于電信行業關鍵任務超高性能生產系統的開發。
在閱讀本文的每個部分之前,強烈建議您參考相關的Java API文檔以獲取詳細信息和代碼示例。
所有測試均針對具有以下特征的Sony Vaio進行:
- 系統:openSUSE 11.1(x86_64)
- 處理器(CPU):Intel(R)Core(TM)2 Duo CPU T6670 @ 2.20GHz
- 處理器速度:1,200.00 MHz
- 總內存(RAM):2.8 GB
- Java:OpenJDK 1.6.0_0 64位
應用以下測試配置:
- 并發工人線程:200
- 每個工作人員重復測試的線程數:1000
- 整體測試次數:100
在多線程環境中使用DateFormat
在多線程環境中使用DateFormat可能很棘手。 Java API文檔明確指出:
“ 日期格式不同步。 建議為每個線程創建單獨的格式實例。 如果多個線程同時訪問一種格式,則必須在外部進行同步。 ”
典型的情況是使用預定義格式將日期轉換為字符串表示形式,反之亦然。 為每次轉換創建新的DateFormat實例效率很低。 您應該記住,靜態工廠方法“ getDateInstance(..)”在使用時也會創建新的DateFormat實例。 大多數開發人員所做的就是使用DateFormat實現類(例如SimpleDateFormat )構造DateFormat實例,并將其值分配給類變量。 類范圍的變量用于其所有日期解析和格式設置需求。 前面提到的方法雖然非常有效,但是由于DateFormat類上缺少同步,因此當多個線程訪問類變量的相同實例時會引起問題。 解析創建Date對象時拋出的典型異常是:
- java.lang.NumberFormatException
- java.lang.ArrayIndexOutOfBoundsException
執行格式化時,您還應該遇到格式錯誤的“ 日期到字符串”表示形式。
為了正確處理上述問題,弄清多線程環境的體系結構至關重要。 Java虛擬機允許應用程序具有多個并行運行的執行線程。 通常,在多線程環境(JVM內部的容器或JVM本身)中,應執行線程池。 工作線程應在啟動時構造并初始化,以用于執行程序。 例如,一個Web容器構造了一個工作線程池來服務所有傳入的流量。 線程池是處理系統資源的最有效方法,主要是因為線程創建和初始化是Java虛擬機的高資源消耗任務。 不過,只需為要同時執行的每段代碼創建一個新的執行線程 ,即可實現應用程序并行性。
關于類范圍的DateFormat實例:
- 如果你已經明確了NO 線程池將在您的環境中使用,那么只有新的主題實例同時訪問你的DateFormat實例。 在這種情況下,建議從外部同步該DateFormat實例
- 如果使用線程池,則可以同時訪問DateFormat實例的線程實例數量有限。 因此,建議使用ThreadLocal方法為每個線程創建單獨的DateFormat實例。
以下是“ getDateInstance(..)”,“同步”和ThreadLocal方法的示例:
package com.javacodegeeks.test;import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date;public class ConcurrentDateFormatAccess {public Date convertStringToDate(String dateString) throws ParseException {return SimpleDateFormat.getDateInstance(DateFormat.MEDIUM).parse(dateString);}}package com.javacodegeeks.test;import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date;public class ConcurrentDateFormatAccess {private DateFormat df = new SimpleDateFormat("yyyy MM dd");public Date convertStringToDate(String dateString) throws ParseException {Date result;synchronized(df) {result = df.parse(dateString);}return result;}}這里要注意的事情:
- 每個執行“ convertStringToDate”操作的線程都試圖在獲取對DateFormat類變量instance的引用之前獲取DateFormat對象的監視器鎖定。 如果另一個線程持有該鎖,則當前線程將等待直到釋放該鎖。 這樣,一次只有一個線程正在訪問DateFormat實例。
這里要注意的事情:
- 每個執行“ convertStringToDate”操作的線程都將調用“ df.get()”操作,以初始化或檢索其本地范圍內的DateFormat實例的已初始化引用。
下面,我們提供上述三種方法之間的性能比較表(注意,我們已經測試了DateFormat實用程序類的解析功能。根據特定的日期格式,我們將日期的String表示形式轉換為等效的Date對象)。
橫軸表示測試運行的次數,縱軸表示每次測試運行的每秒平均事務數(TPS)。 因此,較高的值更好。 如您所見,通過使用線程池和ThreadLocal方法,與“同步”方法和“ getDateInstance(..)”方法相比,您可以獲得更高的性能。
最后,我要指出的是,使用不帶線程池的ThreadLocal方法等同于使用“ getDateInstance(..)”方法,因為每個新線程都必須在使用之前初始化其本地DateFormat實例,因此需要一個新的DateFormat實例將在每次執行時創建。
編碼愉快!
賈斯汀
相關文章 :- Java最佳實踐–高性能序列化
- Java最佳實踐– Vector vs ArrayList vs HashSet
- Java最佳實踐–字符串性能和精確字符串匹配
- Java最佳實踐–隊列之戰和鏈接的ConcurrentHashMap
- Java最佳實踐– Char到Byte和Byte到Char的轉換
翻譯自: https://www.javacodegeeks.com/2010/07/java-best-practices-dateformat-in.html
dateformat線程
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的dateformat线程_Java最佳实践–多线程环境中的DateFormat的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: smartgwt_高级SmartGWT教
- 下一篇: 系统找不到文件怎么办系统找不到文件解决方