研究CodecOutputList实现

先是一个什么都不做的CodecOutputListRecycler,代码如下:

1
2
3
4
5
6
7
8

private static final CodecOutputListRecycler NOOP_RECYCLER = new CodecOutputListRecycler() {
    @Override
    public void recycle(CodecOutputList object) {
        // drop on the floor and let the GC handle it.
    }
};

接下来是一个FastThreadLocal<CodecOutputLists>,代码如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10

private static final FastThreadLocal<CodecOutputLists> CODEC_OUTPUT_LISTS_POOL =
        new FastThreadLocal<CodecOutputLists>() {
            @Override
            protected CodecOutputLists initialValue() throws Exception {
                // 16 CodecOutputList per Thread are cached.
                return new CodecOutputLists(16);
            }
        };

值得注意的是,这块使用的是CodecOutputLists,而并不是CodecOutputList,而在我们ByteToMessageDecoder中使用的是:CodecOutputList out = CodecOutputList.newInstance();

简单看了一下CodecOutputLists的构造函数,它只是初始了一个CodecOutputList数组,然后在里面塞了16个CodecOutputList。

而在在ByteToMessageDecoder中的CodecOutputList.newInstance(),实现上最终调用的是CodecOutputLists的getOrCreate方法。这个方法会先从上面缓存的16个CodecOutputList中拿一个,如果已经被拿完了,则创建一些。

这个过程中有些数字挺迷惑人的,比如创建CodecOutputLists时的16,初始化CodecOutputList数组时的,传递到每个CodecOutputList的16,和最后临时创建的CodecOutputList时传入给构造函数的4。它们都是有不同的含义的,这个晚点我会整理到。

如下代码,我简单测了一下长度带来的影响: