2014-09-05 66 views
2

我有簡單的簡單的JSON序列在我的Spring項目:JSON序列化和線程安全

public class JsonDateTimeSerializer extends JsonSerializer<Date> { 
    private static final DateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 

    @Override 
    public void serialize(Date value, JsonGenerator gen, SerializerProvider sp) throws IOException { 
     gen.writeString(DATE_FORMAT.format(value)); 
    } 
} 

而且使用它像:

@JsonSerialize(using = JsonDateTimeSerializer.class) 
public Date getDate() { 
    return date; 
} 

我一定要照顧線程安全的,並使DATE_FORMAT同步(因爲SimpleDateFormat不是線程安全的)?我不確定@JsonSerialize的工作原理 - 它是否在所有線程上創建了單個序列化的實例?還是它爲每個轉換創建單獨的實例?

回答

0

當傑克遜看到您的首次類型,(取決於類型),它會建立一個BeanSerializer與適當JsonSerializer S代表每個屬性。這BeanSerializer緩存和重新使用相同的Type未來序列化。

因此,JsonDateTimeSerializer(每個類型)的單個實例將被重新用於所有序列化,該實例已被註冊到JsonDateTimeSerializer。因此,如果您計劃跨多個線程使用ObjectMapper,則它必須是線程安全的。 (你應該自ObjectMapper本身是線程安全的。)

3

如果JsonDateTimeSerializer.serialize可能被多個線程調用,那麼這個使用SimpleDateFormat是不安全的。在other answer中解釋了在SimpleDateFormat上避免低效同步的常用方法。適應你的使用情況:

public class JsonDateTimeSerializer extends JsonSerializer<Date> { 

    private static final ThreadLocal<SimpleDateFormat> formatter = new ThreadLocal<SimpleDateFormat>() { 
     @Override 
     protected SimpleDateFormat initialValue() { 
      return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 
     } 
    }; 

    @Override 
    public void serialize(Date value, JsonGenerator gen, SerializerProvider sp) throws IOException { 
     gen.writeString(formatter.get().format(value)); 
    } 
}