我将Jackson JSON处理器包装在自己的类中,但是还没有找到确定的线程安全和高性能的方式来处理共享实例。

根据文档,ObjectMapperObjectWriterObjectReader都是线程安全的,我应该优先使用ObjectWriterObjectReader

处理ObjectWriter非常简单,但是即使在Jackson Data-bind docs上也没有明确的ObjectReader指令,这暗示着我应该创建所有自己的ObjectReaders并缓存它们。所以这就是我所做的:

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectReader;
import com.fasterxml.jackson.databind.ObjectWriter;

import java.util.HashMap;
import java.util.Map;

public class JacksonEngine extends JsonProcessor {

    private ObjectMapper mapper = new ObjectMapper();
    private ObjectWriter writer = mapper.writer();
    private Map<Class, ObjectReader> readers = new HashMap<>();

    public String serialize(Object object) throws Exception {
        return writer.writeValueAsString(object);
    }

    public <T> T deserialize(String json, Class<T> classOfT)
            throws Exception {
        if (!readers.containsKey(classOfT)) {
            readers.put(classOfT, mapper.readerFor(classOfT));
        }
        return readers.get(classOfT).readValue(json);
    }

}

这行得通吗?

我假设必须将哈希映射键的所有通用Class<T>减少为非通用Class都可以。

我还假设在多线程条件下将新的if not present then add放入缓存的非原子Readers操作将不是问题,除非可能会创建一两个冗余读取器。

最后,我认为为了提高性能,值得对Readers进行缓存,即使我没有在网上找到有关这样做的示例。

最佳答案

我认为您实际上并不需要ObjectReaderObjectWriter。它们是线程安全的,因此可以共享。由于您不共享读者和作家,因此可以保持简单:

public class JacksonEngine extends JsonProcessor {

    private final static ObjectMapper mapper = new ObjectMapper();

    public String serialize(Object object) throws Exception {
        return mapper.writeValueAsString(object);
    }

    public <T> T deserialize(String json, Class<T> classOfT)
            throws Exception {
        return mapper.readValue(json, classOfT);
    }

}

更新:

由于OP每次调用新的阅读器时都会在调用ObjectMapper.readValue()时关注性能。查看源代码可以发现情况并非如此:
public <T> T readValue(String content, Class<T> valueType) {
    return (T) _readMapAndClose(_jsonFactory.createParser(content), _typeFactory.constructType(valueType));
}

protected Object _readMapAndClose(JsonParser p0, JavaType valueType) {
    try {
        Object result;
        // ...
        JsonDeserializer<Object> deser = _findRootDeserializer(ctxt, valueType);
        // ...
        result = deser.deserialize(p, ctxt);
        // ...
        return result;
    }
}

09-28 00:24