1. 程式人生 > >執行緒不安全SimpleDateFormat的替換方案DateFormatUtils、DateUtils

執行緒不安全SimpleDateFormat的替換方案DateFormatUtils、DateUtils

1、最近生產環境遇到了一個問題:會員查詢介面,會員返回的開始時間竟然比過期時間大。
vipStart=2018-08-07 18:37:28 vipEnd=2018-08-05 13:29:54

2、會員的開始時間是根據會員的過期時間來計算的(往前推31天)
檢視系統日誌,排除了資料庫、程式碼的計算可能性後,決定用2018-08-07 18:37:28去查詢一下日誌,是否是執行緒切換造成的。
後面查詢到了一個執行緒日誌
vipStart=2018-07-07 18:37:28 vipEnd=2018-08-07 18:37:28

3、明顯是執行緒不安全問題,後面查詢了格式化工具:
public class DateUtils {
private static SimpleDateFormat simpleDateFormat = null;
method1(){}
method2(){}
method3(){}
}

(1)可以看到工具欄中static SimpleDateFormat是執行緒不安全的,當使用不同的pattern進行修改時,產生的日期格式可能不一樣的。
(2)SimpleDateFormat,類內部有一個Calendar物件引用,它用來儲存和這個sdf相關的日期資訊,例如sdf.parse(dateStr), sdf.format(date) 諸如此類的方法引數傳入的日期相關String, Date等等, 都是交由Calendar引用來儲存的.這樣就會導致一個問題,如果你的sdf是個static的, 那麼多個thread 之間就會共享這個SimpleDateFormat, 同時也是共享這個Calendar引用
, 並且, 觀察 sdf.format() 方法,你會發現有如下的呼叫: 
   public StringBuffer format(Date date, StringBuffer toAppendTo,
                               FieldPosition pos)
    {
        pos.beginIndex = pos.endIndex = 0;
        return format(date, toAppendTo, pos.getFieldDelegate());
    }

    // Called from Format after creating a FieldDelegate
    private StringBuffer format(Date date, StringBuffer toAppendTo,
                                FieldDelegate delegate) {
        // Convert input date to time field list
        calendar.setTime(date);
boolean useDateFormatSymbols = useDateFormatSymbols(); for (int i = 0; i < compiledPattern.length; ) { int tag = compiledPattern[i] >>> 8; int count = compiledPattern[i++] & 0xff; if (count == 255) { count = compiledPattern[i++] << 16; count |= compiledPattern[i++]; }

4、替代方案:

(1)將工具類中private static SimpleDateFormat simpleDateFormat = null;去除掉,寫到方法裡面去;

(2)使用threadlocal方式;

(3)使用Apache下面的DateFormatUtils、DateUtils、最主要的區別是執行緒安全、佔用記憶體少。(推薦)

import org.apache.commons.lang.time.DateFormatUtils;

import org.apache.commons.lang.time.DateUtils;

附圖:SimpleDateFormat與DateFormatUtils、DateUtils佔用的記憶體,可以看出apache工具類的優勢。



相關推薦

執行安全SimpleDateFormat替換方案DateFormatUtilsDateUtils

1、最近生產環境遇到了一個問題:會員查詢介面,會員返回的開始時間竟然比過期時間大。vipStart=2018-08-07 18:37:28 vipEnd=2018-08-05 13:29:542、會員的開始時間是根據會員的過期時間來計算的(往前推31天)檢視系統日誌,排除了資

SimpleDateFormat執行安全的!!(NumberFormatException: multiple points)

問題描述: 有兩個專案,一個ssmp、一個性能資料提供perf-provider ,後者給前者提供rest api; 突然有一天,來了新需求,ssmp在短時間內需要傳送大量的rest請求,請求中有一個 時間引數,傳到後臺做時間格式化時開始報錯: 嚴重: Servlet.service

simpleDateFormat執行安全

simpleDateFormat是我們比較常用的日期轉換類,但是它是一個執行緒不安全的類。 舉例證明 public class DateFormatExample1 { //請求總數 private static int clientTotal = 1000; //同時允許執行的執

SimpleDateFormat執行安全導致的問題

轉載 執行緒安全日期格式化操作的幾種方式 由於 DateFormat 是非執行緒安全的,因此在多執行緒併發情況下日期格式化時需要特別注意。下面記錄幾種格式化的方式: 執行緒不安全的處理方式 private static final DateFormat DATE_

SimpleDateFormat時間格式化執行安全問題

想必大家對SimpleDateFormat並不陌生。SimpleDateFormat 是 Java 中一個非常常用的類,該類用來對日期字串進行解析和格式化輸出,但如果使用不小心會導致非常微妙和難以除錯的問題,因為 DateFormat 和 SimpleDateFormat 類

SimpleDateFormat執行安全及解決辦法

一. 為什麼SimpleDateFormat不是執行緒安全的? Java原始碼如下: /** * Date formats are not synchronized. * It is recommended to create separate format instan

執行安全SimpleDateFormat

8.5 SimpleDateFormat是執行緒不安全的 SimpleDateFormat是Java提供的一個格式化和解析日期的工具類,日常開發中應該經常會用到,但是由於它是執行緒不安全的,多執行緒公用一個SimpleDateFormat例項對日期進行解析或者格式化會導致程式出錯,本節就討論下它為何是執行緒

為什麼SimpleDateFormat執行安全? 侵立刪

轉自:https://mp.weixin.qq.com/s/2uzr800WYtu4R0hycfGruA   在日常開發中,我們經常會用到時間相關類,我們有很多辦法在Java程式碼中獲取時間。但是不同的方法獲取到的時間的格式都不盡相同,這時候就需要一種格式化工具,把時間顯示成我們需

SimpleDateFormat時間格式化執行安全問題_2

1. 原因 SimpleDateFormat(下面簡稱sdf)類內部有一個Calendar物件引用,它用來儲存和這個sdf相關的日期資訊,例如sdf.parse(dateStr), sdf.format(date) 諸如此類的方法引數傳入的日期相關String, Date等

HashMap執行安全的表現 -- Java 8

HashMap執行緒不安全的表現 -- Java 8 先來看看HashMap.put方法的原始碼 public V put(K key, V value) { return putVal(hash(key), key, value, false, true); }

String,StringBuffer與StringBuilder的區別|執行安全執行安全

轉載自https://www.cnblogs.com/xingzc/p/6277581.html侵權刪 String 字串常量 StringBuffer 字串變數(執行緒安全) StringBuilder 字串變數(非執行緒安全)  簡要的說, String 型別和 StringBuf

java中為什麼Hashtable是執行安全的,而HashMap是執行安全的?還有ArrayList為什麼是執行安全的,Vector是執行安全的??

文章目錄 一、HashMap解析 二、Hashtable解析 三、Collections.synchronizedMap()解析 四、ConcurrentHashMap 六、ArrayList為什麼是執行緒不安全的,Vector是執行緒安全的?

java.text.DateFormat 執行安全問題

java.text下的 DateFormat 是執行緒不安全的; 建議1: 1、使用threadLocal包裝DateFormat(太複雜,不推薦) 2、使用org.apache.commons.lang3.time.DateFormatUtils下的方法(推薦) DateFormatUtils

HashMap為什麼是執行安全的?

一直以來只是知道HashMap是執行緒不安全的,但是到底HashMap為什麼執行緒不安全,多執行緒併發的時候在什麼情況下可能出現問題? HashMap底層是一個Entry陣列,當發生hash衝突的時候,hashmap是採用連結串列的方式來解決的,在對應的陣列位置存放連結串列

為什麼說ArrayList是執行安全的?

概要介紹 首先說一下什麼是執行緒不安全:執行緒安全就是多執行緒訪問時,採用了加鎖機制,當一個執行緒訪問該類的某個資料時,進行保護,其他執行緒不能進行訪問直到該執行緒讀取完,其他執行緒才可使用。不會出現資料不一致或者資料汙染。執行緒不安全就是不提供資料訪問保護,有可能出現多個執行緒先後更改資料

Java併發程式設計 之 HashMap執行安全

我想在平時的多執行緒程式設計中,容器的使用是很普遍的,但是你有沒有考慮過有些容器是不安全的,如Haspmap、ArrayList。這裡講解一下Hashmap不安去體現在哪裡。 插入時不安全: 如果有兩個執行緒A和B,都進行插入資料,剛好經過雜湊計算後得到的雜湊碼是一樣的,即插入的

p6spy列印sql日誌執行安全導致的生產問題

  首先說明下我這個標題可能起的不到位,其實我本次要介紹的是一次生產定位問題的思路及過程。 1.生產現象    國慶前期釋出了一個很小版本,大家都以為沒什麼問題,可是釋出後生產出現了問題並且持續了兩個小

Java:為什麼說StringBuilder執行安全

一、前言 可能大家在學習java的基礎過程中,都知道StringBuilder相對StringBuffer效率更高,但是執行緒不安全。可是,到底是怎麼個不安全法,反正我是懵的。藉此機會,寫個小程式碼測試下。 二、編碼 既然是測試StringBuilder和StringB

java-雙重檢查鎖為什麼多執行安全

如下程式碼所示: public class doubleCheck{ private static Instance instance; public static Instance getInstance(){ if(instance==null){ //1

ThreadLocal使用注意:執行安全,可能會發生記憶體洩漏

先說可能會發生記憶體洩漏: 前言 ThreadLocal 的作用是提供執行緒內的區域性變數,這種變數線上程的生命週期內起作用,減少同一個執行緒內多個函式或者元件之間一些公共變數的傳遞的複雜度。但是如果濫用ThreadLocal,就可能會導致記憶體洩漏。下面,我們將圍繞三個