idea: Inappropriate blocking method call

Last Modified: 2023/12/10

前情回顾

在 spring cloud gateway filter 中调用 JSON 序列化方法 writeValueAsString 或 writeValueAsBytes 时,idea 中会有一个黄色背景提示“Inappropriate blocking method call”,如下图所示:

难道 json 序列化方法会阻塞吗?

其实 writeValueAsString 方法并不会阻塞,但是为什么 idea 会提示 Inappropriate blocking method call 呢?这可能是 idea 代码分析得出的结论,因为 writeValueAsString 和 writeValueAsBytes 均抛出 JsonProcessingException,而这个 Exception 的父类是 IOException,可能正是这个 IOException 让 idea 认为该方法可能会阻塞。

为了验证这一点,我们可以自定义一个空方法,该方法声明抛出 IOException,然后调用该方法,idea 同样也会提示 Inappropriate blocking method call。

代码分析

再回到刚刚那个问题:“json 序列化方法会阻塞吗?”

答案是有可能会,会与不会取决于输出流,如果输出流是阻塞的那么序列化就可能因为输出流的阻塞而阻塞。writeValueAsString 为什么不会阻塞呢?让我们先看下 writeValueAsString 的代码:

public String writeValueAsString(Object value) throws JsonProcessingException {
    SegmentedStringWriter sw = new SegmentedStringWriter(this._jsonFactory._getBufferRecycler());

    try {
        this._writeValueAndClose(this.createGenerator((Writer)sw), value);
        return sw.getAndClear();
    } catch (JsonProcessingException var4) {
        throw var4;
    } catch (IOException var5) {
        throw JsonMappingException.fromUnexpectedIOE(var5);
    }
}

从这里已经可以看出不可能阻塞,SegmentedStringWriter 会将 json 序列化结果直接写到内部的 buffer 中,整个操作在内存中就完成了,不涉及磁盘 IO 和网络 IO,因此不会阻塞。

结论

JSON 序列化可能会因为输出流的阻塞而阻塞。例如,如果将序列化的结果写入到 servlet 的 outputstream 中,就可能会发生阻塞。

有问题吗?点此反馈!

温馨提示:反馈需要登录