浏览代码

优化房间对象池管理

johnclot69 4 月之前
父节点
当前提交
d1a765354e

+ 1 - 6
incubator-game/src/main/java/com/incubator/game/GGame.java

@@ -23,7 +23,6 @@ import com.incubator.game.data.entity.GlobalInfoPO;
 import com.incubator.game.data.jdbc.LSDBHandler;
 import com.incubator.game.listener.PublicListener;
 import com.incubator.game.player.GPlayer;
-import com.incubator.game.room.Room;
 import com.incubator.game.room.RoomManager;
 import com.incubator.game.timer.FlushDB;
 import com.incubator.game.timer.RefreshNewDay;
@@ -38,7 +37,6 @@ import java.io.File;
 import java.io.FileInputStream;
 import java.util.*;
 import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.LinkedBlockingQueue;
 import java.util.concurrent.ScheduledThreadPoolExecutor;
 import java.util.concurrent.TimeUnit;
 
@@ -102,9 +100,6 @@ public class GGame extends AbstractService {
     /** http消息事件 **/
     public static Map<String, HttpRequestHandler> httpHandlers = new HashMap<>();
 
-    /** 根据房间类型维护独立的对象池 [key:房间类型, value:对象池] **/
-    public static Map<Integer, LinkedBlockingQueue<Room>> roomPool = new ConcurrentHashMap<>();
-
     /** 本服所有在线玩家 */
     public static Map<String, GPlayer> onlinePlayers = new ConcurrentHashMap<>();
 
@@ -240,7 +235,7 @@ public class GGame extends AbstractService {
         //加载数据库数据
 //        this.initAllBlobGameData();
         //初始化 房间服务
-        RoomManager.getInstance().init();
+        RoomManager.getInstance().init(5);
     }
 
 //    private ProtoData.GlobalAllBlobData.Builder initAllBlobGameData() {

+ 2 - 2
incubator-game/src/main/java/com/incubator/game/room/JDGDRoom.java

@@ -60,7 +60,7 @@ public class JDGDRoom extends Room implements GRoomInterface {
                 // 120秒未开始直接解散
 //                if (this.data.time >= 120) {
 //                    logger.debug("解散房间...");
-//                    RoomManager.getInstance().destroyRoom(this.data.roomId);
+//                    this.destroy();
 //                }
                 break;
             case 1:
@@ -111,7 +111,7 @@ public class JDGDRoom extends Room implements GRoomInterface {
                     // 120秒未开始直接解散
 //                    if (this.data.time >= 120) {
 //                        logger.debug("解散房间...");
-//                        RoomManager.getInstance().remove(this.data.roomId);
+//                        this.destroy();
 //                    }
                 }
                 break;

+ 24 - 28
incubator-game/src/main/java/com/incubator/game/room/Room.java

@@ -15,8 +15,10 @@ import java.util.concurrent.TimeUnit;
 public class Room {
 
     protected Logger logger = Log4jUtil.getLogger(getClass());
-    /** 创建一个单线程的 ScheduledExecutorService **/
-    private ScheduledExecutorService scheduler;// = Executors.newSingleThreadScheduledExecutor();
+    /** 激活标记 **/
+    private boolean isActive;
+    /** 房间任务主线程 **/
+    private ScheduledExecutorService scheduler;
     /** 房间数据 **/
     public RoomPO data;
 
@@ -33,43 +35,37 @@ public class Room {
      * 开启房间主线程任务
      */
     public void startRoomTask() {
-        // 启动一个每秒运行一次的任务
-        // 初始延迟为0,后续每隔1秒执行一次
-        // 例如,这里可以检查游戏状态、广播信息、或者更新某些数据
-        this.scheduler.scheduleAtFixedRate(this::doUpdate, 0, 1, TimeUnit.SECONDS);
+        this.isActive = true;
+        this.scheduler.scheduleAtFixedRate(() -> {
+            if (this.isActive) {
+                this.doUpdate();
+            }
+        }, 0, 1, TimeUnit.SECONDS);
     }
 
+    /**
+     * 房间主线程逻辑
+     */
     void doUpdate() {}
 
     /**
-     * 关闭房间主线程任务
+     * 重置房间,用于对象池回收前清理状态
      */
-    private void stopRoomTask() {
-        // 关闭调度器
-        if (this.scheduler != null && !this.scheduler.isShutdown()) {
-            this.scheduler.shutdown();
-            try {
-                if (!this.scheduler.awaitTermination(5, TimeUnit.SECONDS)) {
-                    this.scheduler.shutdownNow();
-                }
-            } catch (InterruptedException e) {
-                logger.error("关闭房间调度器时发生中断", e);
-                this.scheduler.shutdownNow();
-            } finally {
-                this.scheduler = null;
-            }
-        }
+    public void reset() {
+        this.isActive = false;
     }
 
     /**
-     * 重置房间
-     * 用于对象池回收前清理状态
+     * 销毁房间,释放资源
      */
-    public void reset() {
-        // 停止房间任务
-        this.stopRoomTask();
+    public void destroy() {
+        reset();
+        this.scheduler.shutdownNow();
+        this.scheduler = null;
+        // 放回池中
+        RoomManager.getInstance().roomPool.offer(this);
+        logger.debug("销毁房间 : {} 释放资源.", this.data.roomId);
         // 清空房间数据
         this.data = null;
-        logger.info("房间已重置");
     }
 }

+ 56 - 54
incubator-game/src/main/java/com/incubator/game/room/RoomManager.java

@@ -2,15 +2,13 @@ package com.incubator.game.room;
 
 import com.incubator.common.log4j.Log4jUtil;
 import com.incubator.common.util.RandomUtil;
-import com.incubator.game.GGame;
 import com.incubator.game.player.Player;
 import com.incubator.game.util.ProtoUtil;
 import com.incubator.message.proto.CommonProto;
 import org.slf4j.Logger;
 
 import java.util.*;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.*;
 
 /**
  * 房间 管理类
@@ -20,6 +18,12 @@ public class RoomManager {
     protected Logger logger = Log4jUtil.getLogger(getClass());
 
     private static RoomManager instance;
+    /** 房间对象池 **/
+    public Queue<Room> roomPool;
+    /** 最大空闲房间数量 **/
+    private int maxIdleRooms;
+    /** 房间清理线程 **/
+    private ScheduledExecutorService cleaner;
 
     /** 房间缓存 [key:房间类型, value:房间实例] **/
     public Map<Integer, Room> roomMap = new ConcurrentHashMap<>();
@@ -33,9 +37,57 @@ public class RoomManager {
 
     /**
      * 初始化
+     *
+     * @param maxIdleRooms 最大空闲房间数量
      */
-    public void init() {
+    public void init(int maxIdleRooms) {
         logger.info("初始化房间服务...");
+        this.roomPool = new ConcurrentLinkedQueue<>();
+        this.maxIdleRooms = maxIdleRooms;
+        this.cleaner = Executors.newSingleThreadScheduledExecutor();
+        // 定期清理空闲房间
+        this.cleaner.scheduleAtFixedRate(this::cleanIdleRooms, 10, 30, TimeUnit.SECONDS);
+    }
+
+    /**
+     * 获取房间对象
+     *
+     * @param roomType
+     * @return
+     */
+    public Room acquireRoom(int roomType) {
+        Room room = roomPool.poll();
+        if (room == null) {
+            // 创建指定类型的房间
+            room = RoomFactory.createRoom(roomType);
+        }
+        return room;
+    }
+
+    /**
+     * 定期清理空闲房间
+     */
+    private void cleanIdleRooms() {
+        while (roomPool.size() > maxIdleRooms) {
+            Room room = roomPool.poll();
+            if (room != null) {
+                // 销毁房间,释放资源
+                room.destroy();
+            }
+        }
+    }
+
+    /**
+     * 关闭对象池
+     */
+    public void shutdown() {
+        cleaner.shutdownNow();
+        roomPool.forEach(Room::destroy);
+        roomPool.clear();
+    }
+
+    public int getAvailableRooms() {
+        return roomPool.size();
     }
 
     /**
@@ -84,40 +136,6 @@ public class RoomManager {
         return null;
     }
 
-    /**
-     * 获取房间对象
-     *
-     * @param roomType
-     * @return
-     */
-    private Room acquireRoom(int roomType) {
-        LinkedBlockingQueue<Room> pool = GGame.roomPool.computeIfAbsent(roomType, k -> new LinkedBlockingQueue<>(GGame.MAX_ROOM_POOL_SIZE));
-        Room room = pool.poll(); // 尝试从池中取一个对象
-        if (room == null) {
-            room = RoomFactory.createRoom(roomType); // 创建指定类型的房间
-        }
-        return room;
-    }
-
-    /**
-     * 释放房间对象
-     *
-     * @param room
-     * @param roomType
-     */
-    private void releaseRoom(Room room, int roomType) {
-        if (room == null) {
-            return;
-        }
-        // 清理房间对象状态
-        room.reset();
-        LinkedBlockingQueue<Room> pool = GGame.roomPool.computeIfAbsent(roomType, k -> new LinkedBlockingQueue<>(GGame.MAX_ROOM_POOL_SIZE));
-        // 如果池未满,则放回池中
-        if (pool.size() < GGame.MAX_ROOM_POOL_SIZE) {
-            pool.offer(room);
-        }
-    }
-
     /**
      * 创建房间
      *
@@ -136,22 +154,6 @@ public class RoomManager {
         return room;
     }
 
-    /**
-     * 销毁房间
-     *
-     * @param roomId
-     */
-    public void destroyRoom(int roomId, int roomType) {
-        // todo 广播房间解散
-
-        // 移除缓存
-        Room room = this.roomMap.remove(roomId);
-        if (room != null) {
-            // 将房间对象归还对象池
-            this.releaseRoom(room, roomType);
-        }
-    }
-
     /**
      * 加入房间
      *