fastjson1.2.83在某些特殊场景下首次并发对两种类型进行反序列化,结果会发生错误。

ddrv8njm  于 4个月前  发布在  其他
关注(0)|答案(1)|浏览(46)

首次同时(并发)对两种类型进行反序列化结果会发生错误,如果首次没有发生错误后续则不会再发生,而如果首次发生了则后续会一直重复。经过研究是 ParserConfig#deserializers#buckets 映射发生了错误,具体导致原因暂时未知,个人怀疑是初始化时put操作并发导致,但是尚未验证。下面是复现代码(一次不行可以多试几次):

public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(() -> {
            String json = "{\"payload\":{\"data\":[{}]}}";
            for (int i = 0; i < 1000000000; i++) {
                TypeReference<CommonMessage<Class1>> typeReference = new TypeReference<>() {
                };
                CommonMessage<Class1> message = JSON.parseObject(json, typeReference);
                List<Class1> result = message.getPayload().getData();
                try {
                    result.forEach(class1 -> Assert.assertEquals(Class1.class, class1.getClass()));
                } catch (Exception ex) {
                    System.out.println(ex);
                }
            }
        });

        Thread t2 = new Thread(() -> {
            String json = "{\"payload\":{\"data\":[{}]}}";
            for (int i = 0; i < 1000000000; i++) {
                TypeReference<CommonMessage<Class2>> typeReference = new TypeReference<>() {
                };
                CommonMessage<Class2> message = JSON.parseObject(json, typeReference);
                List<Class2> result = message.getPayload().getData();
                try {
                    result.forEach(class2 -> Assert.assertEquals(Class2.class, class2.getClass()));
                } catch (Exception ex) {
                    System.out.println(ex);
                }
            }

        });
        t1.start();
        t2.start();
        t1.join();
        t2.join();
    }

    @Data
    public static class Class1 {
    }

    @Data
    public static class Class2 {
    }

    @EqualsAndHashCode(callSuper = true)
    @Data
    public static class CommonMessage<T> extends CommonRequest<T> {
    }

    @Data
    public static class CommonRequest<T> {
        private Payload<T> payload;
    }

    @Data
    public static class Payload<T> {
        private List<T> data;
    }

上述代码如果没有意外会抛出异常:java.lang.ClassCastException

相关问题