代码之家  ›  专栏  ›  技术社区  ›  Laimoncijus

Jackson的JsonSerializer和线程安全

  •  3
  • Laimoncijus  · 技术社区  · 11 年前

    我有一个简单的 JsonSerializer 在我的Spring项目中:

    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 工作-它是否只在所有线程中创建单个序列化实例?还是为每个转换创建单独的实例?

    2 回复  |  直到 5 年前
        1
  •  4
  •   Community Mohan Dere    9 年前

    如果 JsonDateTimeSerializer.serialize 可以从多个线程调用,那么 SimpleDateFormat 不安全。避免在上进行低效同步的常见方法 日期格式 这一点解释得很好 other answer .适应您的用例:

    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));
        }
    }
    
        2
  •  1
  •   Sotirios Delimanolis    11 年前

    当Jackson第一次看到你的类型时(取决于类型),它将构建一个 BeanSerializer 与适当的 JsonSerializer s表示每个属性。这 光束序列化器 被缓存并在以后的序列化中重复使用 Type .

    因此 JsonDateTimeSerializer (每种类型),将在 JsonDateTimeSerializer ,将用于所有序列化。因此,如果您计划使用 ObjectMapper 跨多个线程。(你应该从 对象映射器 本身是线程安全的。)