Java 杰克逊';s JsonSerializer和线程安全
我的Spring项目中有一个简单的Java 杰克逊';s JsonSerializer和线程安全,java,json,spring,multithreading,jackson-databind,Java,Json,Spring,Multithreading,Jackson Databind,我的Spring项目中有一个简单的JsonSerializer: public class JsonDateTimeSerializer extends JsonSerializer<Date> { private static final DateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); @Override public void serializ
JsonSerializer
:
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));
}
}
我是否必须注意线程安全并使
DATE\u格式
同步(因为SimpleDateFormat
不是线程安全的)?我不确定@JsonSerialize
到底是如何工作的-它是否只在所有线程中创建一个序列化实例?还是为每个转换创建单独的实例?如果可以从多个线程调用JsonDateTimeSerializer.serialize
,那么使用SimpleDateFormat
是不安全的。本文详细解释了在SimpleDataFormat
上避免低效同步的常用方法。适应您的用例:
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));
}
}
公共类JsonDateTimeSerializer扩展了JsonSerializer{
私有静态最终ThreadLocal格式化程序=新ThreadLocal(){
@凌驾
受保护的SimpleDataFormat初始值(){
返回新的SimpleDataFormat(“yyyy-MM-dd HH:MM:ss”);
}
};
@凌驾
public void serialize(日期值、JsonGenerator gen、SerializerProvider sp)引发IOException{
gen.writeString(formatter.get().format(value));
}
}
当Jackson第一次看到您的类型时(取决于类型),它将为每个属性构建一个带有相应的JsonSerializer
的BeanSerializer
。此BeanSerializer
被缓存并重新用于相同类型的未来序列化
因此,已在JsonDateTimeSerializer
中注册的JsonDateTimeSerializer
(每种类型)的单个实例将重新用于所有序列化。因此,如果您计划跨多个线程使用ObjectMapper
,那么它必须是线程安全的。(应该这样做,因为ObjectMapper
本身是线程安全的。)我也遇到过同样的多线程问题,当我添加上述代码时,它就消失了。所以我认为正确的答案是这个问题。
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));
}
}