有个需求:
所有用户在相同的时刻获取到的在线人数数量都是一致的
现在两种方式:
单例模式,和redis的bitmap模式,那个好用
bitmap更好用一些,原因:
bitmap是redis的一个数据结构,可以有效的表达大量的位信息,通过bitmap可以方便记录在线用户的状态,而且Redis本身就支持对Bitmap进行位操作,如设置位,清楚位,统计位等,适合实现在线人数统计。
单例模式确保的是一个类只有一个实例,并提供一个全局访问点。在线人数统计需要被多个用户同时访问和修改,单例模式会限制实例的数量
bitmap
public static void main(String[] args) { // 连接到 Redis 服务 Jedis jedis = new Jedis("localhost", 6379); // 将用户设置为在线(假设用户ID为1001) long userId = 1001; jedis.setbit("online_users", userId, true); // 统计在线人数 long onlineCount = jedis.bitcount("online_users"); System.out.println("当前在线人数:" + onlineCount); // 关闭连接 jedis.close(); }
单例模式
public class OnlineCounter { private static final OnlineCounter instance = new OnlineCounter(); private int onlineCount; private OnlineCounter() { // 初始化在线人数为0 onlineCount = 0; } public static OnlineCounter getInstance() { return instance; } public int getOnlineCount() { return onlineCount; } public void increment() { onlineCount++; } public void decrement() { onlineCount--; } // 其他方法或功能可以根据实际需求添加 public static void main(String[] args) { OnlineCounter counter1 = OnlineCounter.getInstance(); OnlineCounter counter2 = OnlineCounter.getInstance(); counter1.increment(); System.out.println("Counter 1 在线人数:" + counter1.getOnlineCount()); System.out.println("Counter 2 在线人数:" + counter2.getOnlineCount()); } }
单例模式:(类加载的时候就创建实例)
线程的安全性能要求高;实例创建简单;避免多次实例化;频繁访问单例对象
理论上就是本地缓存当redis使用,不怕数据丢失,也不编辑的那种
场景:
常驻内存的对象:整个应用程序的生命周期都需要访问;
全局的配置对象:程序的配置信息,比如数据库连接信息、日志级别等等
工具类:类似于时间处理工具类,加密工具类,不需要多个实例
举个例子
public static void main(String[] args) { // 获取 DateUtil 实例 DateUtil dateUtil = DateUtil.getInstance(); // 使用 DateUtil 实例中的方法 String currentDate = dateUtil.getCurrentDate(); System.out.println("Current date: " + currentDate); Date inputDate = new Date(); String formattedDate = dateUtil.formatToYYYYMMDD(inputDate); System.out.println("Formatted date: " + formattedDate); } class DateUtil { // 使用饿汉式单例模式创建实例 private static final DateUtil instance = new DateUtil(); // 私有构造方法,避免外部实例化 private DateUtil() { // 进行初始化操作,如果有的话 } // 获取实例的静态方法 public static DateUtil getInstance() { return instance; } // 其他日期处理方法 public String getCurrentDate() { // 返回当前日期的逻辑 return "2024-03-28"; } // 其他日期处理方法 public String formatToYYYYMMDD(Date date) { // 将日期格式化为yyyy-MM-dd的逻辑 return "Formatted date: " + date.toString(); } }