「这是我参与11月更文挑战的第21天,活动详情查看:2021最后一次更文挑战」
一、什么是@Sharable
首先我们看下如下的代码:
1 | scss复制代码public class Server { |
在上述的代码当中,有三个handler,而这三个handler是针对每一个SocketChannel 的,当连接数很多的时候,可能需要创建大量的handler实例,占据大量的内存空间。
那么是否能够将handler提出来作为公共使用呢?
当然是可以的,但是要考虑两种handler是否存在线程安全问题。
这里就可以使用这个注解@Sharable来表示。
其注释的含义如下所示:
表示可以将带注释的ChannelHandler的同一实例多次添加到一个或多个ChannelPipeline ,而不会出现竞争条件。
如果未指定此注解,则每次将其添加到管道时都必须创建一个新的处理程序实例,因为它具有成员变量等非共享状态。
二、使用@Sharable
首先我们看下前一章节当中自己创建的编解码器,添加上该注解后,是否能够正常使用。
1 | ini复制代码/** |
添加上之后就㞏正常启动客户端了。分析一下问题,看MessageCodec 继承了ByteToMessageCodec,我们跟踪源码进去看看。因为我们的这个类没有构造方法,所以直接去看父类ByteToMessageCodec的构造方法:
1 | ini复制代码 protected ByteToMessageCodec(boolean preferDirect) { |
有一个 ensureNotSharable()的方法,直译过来就是确保不是可共享的。
1 | csharp复制代码 protected void ensureNotSharable() { |
如果是,就抛出异常。
其实在ByteToMessageCodec这个类的注释上就表明了这个类的子类必须不是可共享的。如下所示。
1 | scala复制代码/** |
那么想让我们的handler变成可共享的要怎么办 ?
第一、只要保证我们的handler没有成员变量等非共享状态。
第二、修改继承的父类,对于编解码器类,不能继承 ByteToMessageCodec 或 CombinedChannelDuplexHandler 父类,他们的构造方法对 @Sharable 有限制。
第三、可以使用MessageToMessageCodec 父类作为父类。
满足以上就可以让我们自己的handler使用@Sharable注解了。
本章就到此为止,有用的话,点个赞再走吧~~
本文转载自: 掘金