Java 杰克逊';s JsonSerializer和线程安全

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

我的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 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));
    }
}