当前位置: 首页 > news >正文

实战-单例模式和创建生产者相结合

实际中遇到了这样一个问题:
The producer group[xxxx] has been created before, specify another instanceName (like producer.setInstanceName) please.
发生的原因是:一个进程内,创建了多个相同topic的producer。
所以问题就转换成了如何避免进程内多个实例的创建。(还有一个解决办法就是producer.setInstanceName(UUID.getUUID()))
解决问题:就要用到了单例模式。
单例模式可以参考:synchronized能不能保证有序性??单例模式下的懒汉和双检锁的思考


分析:
为啥不用分布式锁呢?分布式其实保证集群内唯一,就是不管你有多少台机器,全局就一个,唯一的一个。
分布式环境,其实就是不同的进程间的问题。集群内唯一,实质就是进程间唯一

“进程唯一”指的是进程内唯一、进程间不唯一。“线程唯一”指的是线程内唯一、线程间不唯一。集群相当于多个进程构成的一个集合,“集群唯一”就相当于是进程内唯一、进程间也唯一。也就是说,不同的进程间共享同一个对象,不能创建同一个类的多个对象。

我们知道,经典的单例模式是进程内唯一的,那如何实现一个进程间也唯一的单例呢?如果严格按照不同的进程间共享同一个对象来实现,那集群唯一的单例实现起来就有点难度了。

具体来说,我们需要把这个单例对象序列化并存储到外部共享存储区(比如文件)。进程在使用这个单例对象的时候,需要先从外部共享存储区中将它读取到内存,并反序列化成对象,然后再使用,使用完成之后还需要再存储回外部共享存储区。

为了保证任何时刻,在进程间都只有一份对象存在,一个进程在获取到对象之后,需要对对象加锁,避免其他进程再将其获取。在进程使用完这个对象之后,还需要显式地将对象从内存中删除,并且释放对对象的加锁。


1.如何理解单例模式的唯一性?

单例类中对象的唯一性的作用范围是“进程唯一”的。“进程唯一”指的是进程内唯一,进程间不唯一;“线程唯一”指的是线程内唯一,线程间可以不唯一。实际上,“进程唯一”就意味着线程内、线程间都唯一,这也是“进程唯一”和“线程唯一”的区别之处。“集群唯一”指的是进程内唯一、进程间也唯一。

2.如何实现线程唯一的单例?

我们通过一个HashMap来存储对象,其中key是线程ID,value是对象。这样我们就可以做到,不同的线程对应不同的对象,同一个线程只能对应一个对象。实际上,Java语言本身提供了ThreadLocal并发工具类,可以更加轻松地实现线程唯一单例。

3.如何实现集群环境下的单例?

我们需要把这个单例对象序列化并存储到外部共享存储区(比如文件)。进程在使用这个单例对象的时候,需要先从外部共享存储区中将它读取到内存,并反序列化成对象,然后再使用,使用完成之后还需要再存储回外部共享存储区。为了保证任何时刻在进程间都只有一份对象存在,一个进程在获取到对象之后,需要对对象加锁,避免其他进程再将其获取。在进程使用完这个对象之后,需要显式地将对象从内存中删除,并且释放对对象的加锁。

4.如何实现一个多例模式?

“单例”指的是一个类只能创建一个对象。对应地,“多例”指的就是一个类可以创建多个对象,但是个数是有限制的,比如只能创建3个对象。多例的实现也比较简单,通过一个Map来存储对象类型和对象之间的对应关系,来控制对象的个数。

参考
1.https://blog.51cto.com/u_15273875/2917903
2.王铮《设计模式之美》

http://www.lryc.cn/news/100896.html

相关文章:

  • [SQL挖掘机] - 窗口函数介绍
  • 原生js实现锚点滚动顶部
  • 使用mysql接口遇到点问题
  • excel绘制折线图或者散点图
  • ChatGPT长文本对话输入方法
  • FFmpeg-swresample的更新
  • 回答网友 修改一个exe
  • 数据可视化 - 动态柱状图
  • 【JVM】JVM五大内存区域介绍
  • 自动驾驶感知系统--惯性导航定位系统
  • Netty简介
  • 基于TCP/IP对等模型对计算机网络知识点的整合
  • 【SQL应知应会】表分区(一)• Oracle版
  • PostgreSQL 常用空间处理函数
  • ubuntu初始化/修改root密码
  • 【Linux后端服务器开发】select多路转接IO服务器
  • 支持向量机(iris)
  • 24考研数据结构-第二章:线性表
  • Mybatis 动态 sql 是做什么的?都有哪些动态 sql?能简述动态 sql 的执行原理不?
  • 250_C++_typedef std::function<int(std::vector<int> vtBits)> fnChkSstStt
  • 无涯教程-jQuery - Transfer方法函数
  • openGauss学习笔记-24 openGauss 简单数据管理-模式匹配操作符
  • JAVASE---数据类型与变量
  • IDEA Groovy 脚本一键生成实体类<mybatisplus>
  • 无涯教程-jQuery - Puff方法函数
  • 什么叫前后端分离?为什么需要前后端问题?解决了什么问题?
  • Vector<T> 动态数组(随机访问迭代器)(答案)
  • Istio 故障注入与重试的实验
  • Java设计模式-中介者模式
  • OpenCV实现高斯模糊加水印