|
@@ -1,6 +1,8 @@
|
|
|
package com.incubator.game.room;
|
|
|
|
|
|
+import java.util.Map;
|
|
|
import java.util.Queue;
|
|
|
+import java.util.concurrent.ConcurrentHashMap;
|
|
|
import java.util.concurrent.ConcurrentLinkedQueue;
|
|
|
import java.util.concurrent.Executors;
|
|
|
import java.util.concurrent.ScheduledExecutorService;
|
|
@@ -11,12 +13,12 @@ import java.util.concurrent.TimeUnit;
|
|
|
*/
|
|
|
public final class RoomPool {
|
|
|
|
|
|
- /** 房间对象池 **/
|
|
|
- public Queue<Room> roomPool;
|
|
|
+ /** 房间对象池,按玩法类型存储不同队列 **/
|
|
|
+ private final Map<Integer, Queue<Room>> roomPools;
|
|
|
/** 最大空闲房间数量 **/
|
|
|
- private int maxIdleRooms;
|
|
|
+ private final int maxIdleRooms;
|
|
|
/** 房间清理线程 **/
|
|
|
- private ScheduledExecutorService cleaner;
|
|
|
+ private final ScheduledExecutorService cleaner;
|
|
|
|
|
|
/**
|
|
|
* 初始化
|
|
@@ -24,7 +26,7 @@ public final class RoomPool {
|
|
|
* @param maxIdleRooms 最大空闲房间数量
|
|
|
*/
|
|
|
public RoomPool(int maxIdleRooms) {
|
|
|
- this.roomPool = new ConcurrentLinkedQueue<>();
|
|
|
+ this.roomPools = new ConcurrentHashMap<>();
|
|
|
this.maxIdleRooms = maxIdleRooms;
|
|
|
this.cleaner = Executors.newSingleThreadScheduledExecutor();
|
|
|
// 定期清理空闲房间
|
|
@@ -35,10 +37,13 @@ public final class RoomPool {
|
|
|
* 获取房间对象
|
|
|
*
|
|
|
* @param gameType 玩法类型 1:掼蛋 2:转蛋
|
|
|
- * @return
|
|
|
+ * @return 房间对象
|
|
|
*/
|
|
|
public Room acquireRoom(int gameType) {
|
|
|
- Room room = this.roomPool.poll();
|
|
|
+ // 获取对应类型的房间队列
|
|
|
+ Queue<Room> pool = this.roomPools.computeIfAbsent(gameType, k -> new ConcurrentLinkedQueue<>());
|
|
|
+ // 从队列中取房间
|
|
|
+ Room room = pool.poll();
|
|
|
if (room == null) {
|
|
|
// 创建指定类型的房间
|
|
|
room = RoomFactory.createRoom(gameType);
|
|
@@ -48,10 +53,14 @@ public final class RoomPool {
|
|
|
|
|
|
/**
|
|
|
* 归还房间对象
|
|
|
+ *
|
|
|
+ * @param room 归还的房间
|
|
|
*/
|
|
|
public void releaseRoom(Room room) {
|
|
|
if (room != null) {
|
|
|
- this.roomPool.offer(room); // 放回池中
|
|
|
+ // 获取对应类型的房间队列
|
|
|
+ Queue<Room> pool = this.roomPools.computeIfAbsent(room.data.gameType, k -> new ConcurrentLinkedQueue<>());
|
|
|
+ pool.offer(room); // 放回队列中
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -59,11 +68,14 @@ public final class RoomPool {
|
|
|
* 定期清理空闲房间
|
|
|
*/
|
|
|
private void cleanIdleRooms() {
|
|
|
- while (this.roomPool.size() > maxIdleRooms) {
|
|
|
- Room room = this.roomPool.poll();
|
|
|
- if (room != null) {
|
|
|
- // 销毁房间,释放资源
|
|
|
- room.destroy();
|
|
|
+ for (Map.Entry<Integer, Queue<Room>> entry : this.roomPools.entrySet()) {
|
|
|
+ Queue<Room> pool = entry.getValue();
|
|
|
+ while (pool.size() > this.maxIdleRooms) {
|
|
|
+ Room room = pool.poll();
|
|
|
+ if (room != null) {
|
|
|
+ // 销毁房间,释放资源
|
|
|
+ room.destroy();
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -73,11 +85,30 @@ public final class RoomPool {
|
|
|
*/
|
|
|
public void shutdown() {
|
|
|
this.cleaner.shutdownNow();
|
|
|
- this.roomPool.forEach(Room::destroy);
|
|
|
- this.roomPool.clear();
|
|
|
+ this.roomPools.values().forEach(pool -> {
|
|
|
+ pool.forEach(Room::destroy);
|
|
|
+ pool.clear();
|
|
|
+ });
|
|
|
+ this.roomPools.clear();
|
|
|
}
|
|
|
|
|
|
- public int getAvailableRooms() {
|
|
|
- return this.roomPool.size();
|
|
|
+ /**
|
|
|
+ * 获取指定玩法类型的可用房间数量
|
|
|
+ *
|
|
|
+ * @param gameType 玩法类型
|
|
|
+ * @return 可用房间数量
|
|
|
+ */
|
|
|
+ public int getAvailableRooms(int gameType) {
|
|
|
+ Queue<Room> pool = this.roomPools.get(gameType);
|
|
|
+ return pool == null ? 0 : pool.size();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取所有玩法类型的房间总数量
|
|
|
+ *
|
|
|
+ * @return 总房间数量
|
|
|
+ */
|
|
|
+ public int getTotalAvailableRooms() {
|
|
|
+ return this.roomPools.values().stream().mapToInt(Queue::size).sum();
|
|
|
}
|
|
|
}
|