src/main/java/com/alipay/remoting/codec/AbstractBatchDecoder.java
@Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        if (msg instanceof ByteBuf) {
            RecyclableArrayList out = RecyclableArrayList.newInstance();
            try {
                ByteBuf data = (ByteBuf) msg;
                first = cumulation == null;
                if (first) {
                    cumulation = data;
                } else {
                    cumulation = cumulator.cumulate(ctx.alloc(), cumulation, data);
                }
                callDecode(ctx, cumulation, out);
            } catch (DecoderException e) {
                throw e;
            } catch (Throwable t) {
                throw new DecoderException(t);
            } finally {
                if (cumulation != null && !cumulation.isReadable()) {
                    numReads = 0;
                    cumulation.release();
                    cumulation = null;
                } else if (++numReads >= discardAfterReads) {
                    // We did enough reads already try to discard some bytes so we not risk to see a OOME.
                    // See https://github.com/netty/netty/issues/4275
                    numReads = 0;
                    discardSomeReadBytes();
                }

                int size = out.size();
                if (size == 0) {
                    decodeWasNull = true;
                } else if (size == 1) {
                    ctx.fireChannelRead(out.get(0));
                } else {
                    ArrayList<Object> ret = new ArrayList<Object>(size);
                    for (int i = 0; i < size; i++) {
                        ret.add(out.get(i));
                    }
                    ctx.fireChannelRead(ret);
                }

                out.recycle();
            }
        } else {
            ctx.fireChannelRead(msg);
        }
    }
@Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        if (msg instanceof ByteBuf) {
            RecyclableArrayList out = RecyclableArrayList.newInstance();
            try {
                ByteBuf data = (ByteBuf) msg;
                first = cumulation == null;
                if (first) {
                    cumulation = data;
                } else {
                    cumulation = cumulator.cumulate(ctx.alloc(), cumulation, data);
                }
                callDecode(ctx, cumulation, out);
            } catch (DecoderException e) {
                throw e;
            } catch (Throwable t) {
                throw new DecoderException(t);
            } finally {
                if (cumulation != null && !cumulation.isReadable()) {
                    numReads = 0;
                    cumulation.release();
                    cumulation = null;
                } else if (++numReads >= discardAfterReads) {
                    // We did enough reads already try to discard some bytes so we not risk to see a OOME.
                    // See https://github.com/netty/netty/issues/4275
                    numReads = 0;
                    discardSomeReadBytes();
                }

                int size = out.size();
                if (size == 0) {
                    decodeWasNull = true;
                } else if (size == 1) {
                    ctx.fireChannelRead(out.get(0));
                } else {
                    ArrayList<Object> ret = new ArrayList<Object>(size);
                    for (int i = 0; i < size; i++) {
                        ret.add(out.get(i));
                    }
                    ctx.fireChannelRead(ret);
                }

                out.recycle();
            }
        } else {
            ctx.fireChannelRead(msg);
        }
    }
@ Override public void channelRead ( ChannelHandlerContext ctx , Object msg ) throws Exception { if ( msg instanceof ByteBuf ) { RecyclableArrayList out = RecyclableArrayList . newInstance ( ) ; try { ByteBuf data = ( ByteBuf ) msg ; first = cumulation == null ; if ( first ) { cumulation = data ; } else { cumulation = cumulator . cumulate ( ctx . alloc ( ) , cumulation , data ) ; } callDecode ( ctx , cumulation , out ) ; } catch ( DecoderException e ) { throw e ; } catch ( Throwable t ) { throw new DecoderException ( t ) ; } finally { if ( cumulation != null && ! cumulation . isReadable ( ) ) { numReads = 0 ; cumulation . release ( ) ; cumulation = null ; } else if ( ++ numReads >= discardAfterReads ) { // We did enough reads already try to discard some bytes so we not risk to see a OOME. // See https://github.com/netty/netty/issues/4275 numReads = 0 ; discardSomeReadBytes ( ) ; } int size = out . size ( ) ; if ( size == 0 ) { decodeWasNull = true ; } else if ( size == 1 ) { ctx . fireChannelRead ( out . get ( 0 ) ) ; } else { ArrayList < Object > ret = new ArrayList < Object > ( size ) ; for ( int i = 0 ; i < size ; i ++ ) { ret . add ( out . get ( i ) ) ; } ctx . fireChannelRead ( ret ) ; } out . recycle ( ) ; } } else { ctx . fireChannelRead ( msg ) ; } }
This method has been modified to check the size of decoded msgs, which is represented by the
local variable {@code RecyclableArrayList out}. If has decoded more than one msg,
then construct an array list to submit all decoded msgs to the pipeline.

@param ctx channel handler context
@param msg data
This method has been modified to check the size of decoded msgs which is represented by the local variable { @code RecyclableArrayList out } . If has decoded more than one msg then construct an array list to submit all decoded msgs to the pipeline .