使用Netty 4,如何在处理程序中抛出异常时如何处理引用计数对象?

时间:2017-12-07 00:32:18

标签: java netty

假设我有一个这样的入站通道处理程序:

public class Handler extends ChannelInboundHandlerAdapter {                                                                                                                                                                                                                 

    @Override                                                                                                                                                                                                                                                               
    protected void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {                                                                                                                                                                                    
        // msg is actually a reference counted object                                                                                                                                                                                                                       
    }                                                                                                                                                                                                                                                                       

    @Override                                                                                                                                                                                                                                                               
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {                                                                                                                                                                              
        // Handle exception here, can't release msg since it's not passed.                                                                                                                                                                                                  
    }                                                                                                                                                                                                                                                                       
}

由于exceptionCaught在其签名中未收到入站消息,因此似乎无法确保释放引用计数对象。看来我被迫将channelRead的全部内容包装在try / catch块中,以确保我可以正常恢复任何异常,而不会终止整个过程。这是真的吗?

1 个答案:

答案 0 :(得分:1)

您应该在try-finally中释放引用计数对象,如Netty quick start tutorial所示。

这可以按如下方式完成:

public class Handler extends ChannelInboundHandlerAdapter {                                                                                                                                                                                                                 

    @Override                                                                                                                                                                                                                                                               
    protected void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {                                                                                                                                                                                    
        try {
            // msg is actually a reference counted object 
        } finally {
            ReferenceCountUtil.release(msg);
        }                                                                                                                                                                                                     
    }                                                                                                                                                                                                                                                                       

    @Override                                                                                                                                                                                                                                                               
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {                                                                                                                                                                              
        // Handle exception here, can't release msg since it's not passed.                                                                                                                                                                                                  
    }                                                                                                                                                                                                                                                                       
}

请注意,我已调用ReferenceCountUtil.release(msg);而不是msg.release(),这是因为调用第一个会自动检查相关对象是否可以被释放,而对于后者则需要强制转换在调用release方法之前,将对象转换为其他类型。