From 115a607adc03ce50ee53a5afd88d5c526e4060df Mon Sep 17 00:00:00 2001 From: zhouwei <849588297@qq.com> Date: Fri, 27 Feb 2026 19:04:53 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=9C=BA=E5=99=A8=E4=BA=BA?= =?UTF-8?q?=E5=B9=B6=E5=8F=91=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/group/job/UpdatePlayRoomJob.java | 89 +++++++++++++----- .../com/group/job/UpdateRobotRoomJob.java | 91 ++++++++++++++----- .../com/group/service/GroupRoomService.java | 2 +- 3 files changed, 136 insertions(+), 46 deletions(-) diff --git a/game_web/web_group/src/main/java/com/group/job/UpdatePlayRoomJob.java b/game_web/web_group/src/main/java/com/group/job/UpdatePlayRoomJob.java index 5560131..a68c078 100644 --- a/game_web/web_group/src/main/java/com/group/job/UpdatePlayRoomJob.java +++ b/game_web/web_group/src/main/java/com/group/job/UpdatePlayRoomJob.java @@ -562,35 +562,65 @@ public class UpdatePlayRoomJob implements Job{ public int getRobot(int maxPlayers) { - long freeRobotNum = Redis.use("group1_db1").scard("free_robot"); - if (freeRobotNum < maxPlayers) - { - long useRobotNum = Redis.use("group1_db1").scard("used_robot"); - if (useRobotNum >= 100) - { - logger.warn("robot not enough, cur used robot " + useRobotNum); + Jedis jedis = Redis.use("group1_db1").getJedis(); + String lockValue = null; + try { + //按房间类型区分 + String lockKey = "robot_allocation_lock_" + maxPlayers; + lockValue = System.currentTimeMillis() + "_" + Thread.currentThread().getId(); + + boolean locked = false; + for (int i = 0; i < 50; i++) { + String result = jedis.set(lockKey, lockValue, "NX", "EX", 15); + if ("OK".equals(result)) { + locked = true; + break; + } + Thread.sleep(50); } - try { - createRobot(); - freeRobotNum = Redis.use("group1_db1").scard("free_robot"); - if (freeRobotNum < maxPlayers) + + if (!locked) { + logger.warn("获取机器人分配锁超时,maxPlayers:" + maxPlayers + ", 返回0"); + return 0; + } + + //检查是否有足够的机器人 + long freeRobotNum = jedis.scard("free_robot"); + long usedRobotNum = jedis.scard("used_robot"); + logger.info("机器人资源状态 - 可用:" + freeRobotNum + ", 已使用:" + usedRobotNum + ", 需要:" + maxPlayers); + if (freeRobotNum < maxPlayers) + { + long useRobotNum = jedis.scard("used_robot"); + logger.warn("机器人数量不足,当前可用:" + freeRobotNum + ", 已使用:" + useRobotNum + ", 需要:" + maxPlayers); + + //如果机器人总数接近上限 + if (useRobotNum + freeRobotNum >= 100) { - logger.error("create robot failed............"); + logger.warn("机器人总数接近上限:" + (useRobotNum + freeRobotNum) + ", 考虑增加机器人容量"); + } + + try { + createRobot(); + freeRobotNum = jedis.scard("free_robot"); + if (freeRobotNum < maxPlayers) + { + logger.error("创建机器人后仍然不足,可用:" + freeRobotNum + ", 需要:" + maxPlayers); + return 0; + } + logger.info("成功创建机器人,当前可用:" + freeRobotNum); + + } + catch (Exception e) + { + logger.error("创建机器人时发生异常: " + e.getMessage(), e); return 0; } - } - catch (Exception e) - { - logger.error(e); - } - } - try { while(freeRobotNum > 0) { - String strRobotId = Redis.use("group1_db1").spop("free_robot"); - freeRobotNum = Redis.use("group1_db1").scard("free_robot"); + String strRobotId = jedis.spop("free_robot"); + freeRobotNum = jedis.scard("free_robot"); if (StringUtil.isEmpty(strRobotId)) { createRobot(); @@ -626,7 +656,7 @@ public class UpdatePlayRoomJob implements Job{ } } - Redis.use("group1_db1").sadd("used_robot", strRobotId); + jedis.sadd("used_robot", strRobotId); int robotId = Integer.parseInt(strRobotId); String fakeHp = Redis.use("group1_db10").hget("fake_"+strRobotId, "fake_hp"); if (StringUtil.isEmpty(fakeHp)) @@ -641,6 +671,21 @@ public class UpdatePlayRoomJob implements Job{ { logger.error(e); } + finally { + // 释放锁 + try { + if (lockValue != null) { + String lockKey = "robot_allocation_lock_" + maxPlayers; + String currentValue = jedis.get(lockKey); + if (lockValue.equals(currentValue)) { + jedis.del(lockKey); + } + } + } catch (Exception e) { + logger.error("释放机器人分配锁时出错: " + e.getMessage()); + } + jedis.close(); + } return 0; } diff --git a/game_web/web_group/src/main/java/com/group/job/UpdateRobotRoomJob.java b/game_web/web_group/src/main/java/com/group/job/UpdateRobotRoomJob.java index c8db360..e4a2b48 100644 --- a/game_web/web_group/src/main/java/com/group/job/UpdateRobotRoomJob.java +++ b/game_web/web_group/src/main/java/com/group/job/UpdateRobotRoomJob.java @@ -711,35 +711,65 @@ public class UpdateRobotRoomJob implements Job{ public int getRobot(int maxPlayers) { - long freeRobotNum = Redis.use("group1_db1").scard("free_robot"); - if (freeRobotNum < maxPlayers) - { - long useRobotNum = Redis.use("group1_db1").scard("used_robot"); - if (useRobotNum >= 100) - { - logger.warn("robot not enough, cur used robot " + useRobotNum); + Jedis jedis = Redis.use("group1_db1").getJedis(); + String lockValue = null; + try { + //按房间类型区分 + String lockKey = "robot_allocation_lock_" + maxPlayers; + lockValue = System.currentTimeMillis() + "_" + Thread.currentThread().getId(); + + boolean locked = false; + for (int i = 0; i < 50; i++) { + String result = jedis.set(lockKey, lockValue, "NX", "EX", 15); + if ("OK".equals(result)) { + locked = true; + break; + } + Thread.sleep(50); } - try { - createRobot(); - freeRobotNum = Redis.use("group1_db1").scard("free_robot"); - if (freeRobotNum < maxPlayers) + + if (!locked) { + logger.warn("获取机器人分配锁超时,maxPlayers:" + maxPlayers + ", 返回0"); + return 0; + } + + //检查是否有足够的机器人 + long freeRobotNum = jedis.scard("free_robot"); + long usedRobotNum = jedis.scard("used_robot"); + logger.info("机器人资源状态 - 可用:" + freeRobotNum + ", 已使用:" + usedRobotNum + ", 需要:" + maxPlayers); + if (freeRobotNum < maxPlayers) + { + long useRobotNum = jedis.scard("used_robot"); + logger.warn("机器人数量不足,当前可用:" + freeRobotNum + ", 已使用:" + useRobotNum + ", 需要:" + maxPlayers); + + //如果机器人总数接近上限 + if (useRobotNum + freeRobotNum >= 100) { - logger.error("create robot failed............"); - return 0; + logger.warn("机器人总数接近上限:" + (useRobotNum + freeRobotNum) + ", 考虑增加机器人容量"); } - } - catch (Exception e) - { - logger.error(e); - } - } + try { + createRobot(); + freeRobotNum = jedis.scard("free_robot"); + if (freeRobotNum < maxPlayers) + { + logger.error("创建机器人后仍然不足,可用:" + freeRobotNum + ", 需要:" + maxPlayers); + return 0; + } + logger.info("成功创建机器人,当前可用:" + freeRobotNum); + + } + catch (Exception e) + { + logger.error("创建机器人时发生异常: " + e.getMessage(), e); + return 0; + } + } - try { while(freeRobotNum > 0) { - String strRobotId = Redis.use("group1_db1").spop("free_robot"); - freeRobotNum = Redis.use("group1_db1").scard("free_robot"); + String strRobotId = jedis.spop("free_robot"); + freeRobotNum = jedis.scard("free_robot"); if (StringUtil.isEmpty(strRobotId)) { createRobot(); @@ -775,7 +805,7 @@ public class UpdateRobotRoomJob implements Job{ } } - Redis.use("group1_db1").sadd("used_robot", strRobotId); + jedis.sadd("used_robot", strRobotId); int robotId = Integer.parseInt(strRobotId); String fakeHp = Redis.use("group1_db10").hget("fake_"+strRobotId, "fake_hp"); if (StringUtil.isEmpty(fakeHp)) @@ -790,6 +820,21 @@ public class UpdateRobotRoomJob implements Job{ { logger.error(e); } + finally { + //释放锁 + try { + if (lockValue != null) { + String lockKey = "robot_allocation_lock_" + maxPlayers; + String currentValue = jedis.get(lockKey); + if (lockValue.equals(currentValue)) { + jedis.del(lockKey); + } + } + } catch (Exception e) { + logger.error("释放机器人分配锁时出错: " + e.getMessage()); + } + jedis.close(); + } return 0; } diff --git a/game_web/web_group/src/main/java/com/group/service/GroupRoomService.java b/game_web/web_group/src/main/java/com/group/service/GroupRoomService.java index 56bd78e..50a5219 100644 --- a/game_web/web_group/src/main/java/com/group/service/GroupRoomService.java +++ b/game_web/web_group/src/main/java/com/group/service/GroupRoomService.java @@ -1328,7 +1328,7 @@ public class GroupRoomService { for (int i = 0; i < players.size(); i++) { int player_id = players.getInt(i); Redis.use("group1_db1").srem("used_robot", Integer.toString(player_id)); - //Redis.use("group1_db1").sadd("free_robot", Integer.toString(player_id)); + Redis.use("group1_db1").sadd("free_robot", Integer.toString(player_id)); } }