单例模式真香

之前对单例模式的印象停留在了各种骚操作保证只有一个实例,一个就一个呗,天天CRUD也想不到有什么用的地方呀,除了准备面试前会写一写,好像还真没怎么写过单例模式。今天着实真香了一把,不过香在单例模式的另一个特性。

是这样的,项目客户端和服务器之间的通信框架是Netty,客户端与服务器绑定成功后可以从ChannelFuture中拿到与Netty服务端建立的通道Channel,往里面写数据就可以将消息发给服务器了。

然后就在想有没有好点的办法把这个Channel缓存起来,想什么时候发消息了就拿出来用一下。缓存的办法倒是挺多的,可是得保证一会没用这个Channel可不能被GC回收了呀。

这个时候单例模式在脑海里亮了一个电灯泡!先看一下这个单例的SingleChannel怎么写的,将initInstance()和getInstance()区分开了。

拿到Channel后先初始化SingleChannel

然后想写数据的时候

 然后解释一下为什么这个单例SingleChannel对象不会被GC回收,当然除非JVM退出。对象被回收是需要对象和GC ROOT之间不可达,而GC ROOT其中有一条就是类的静态属性引用,在单例模式中SingleChannel对象被自己类的静态属性引用着,就一直可达了呀。想要回收这个对象,除非SingleChannel类被回收了,作为该类的属性它的内存空间自然要被释放。那类被回收有什么条件呢?其中有一条就是该类所有的实例已经被回收!哦吼,掐上了,想回收这个实例得等这个类卸载,想卸载这个类又要等回收这个实例,我怎么忽然想到了线程死锁,虽然没什么关系,但是两者的场景简直一模一样。

我是用双重否定检查来创建单例的,现在不是流行用枚举类来创建实例嘛,各种好,具体怎么好这里就不说了,想说一下用枚举类来创建实例是不是也能达到这种避免被回收的效果?答案是可以的。

看一下枚举类创建单例反编译后的样子,网上找了一张图

这样也就能看出来了,类的实例被自己的静态属性引用着。 

发布了76 篇原创文章 · 获赞 57 · 访问量 10万+

猜你喜欢

转载自blog.csdn.net/weixin_42447959/article/details/102734275