修改长沙麻将线程池
parent
74ce44217e
commit
032cd2d46c
|
|
@ -22,6 +22,9 @@ import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import static robot.mj.thread.ThreadPoolConfig.scheduleDelay;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 长沙麻将游戏控制器 - 处理游戏协议
|
* 长沙麻将游戏控制器 - 处理游戏协议
|
||||||
|
|
@ -150,7 +153,10 @@ public class EXGameController extends GameController {
|
||||||
|
|
||||||
GroupRoomBusiness.joinRoom(groupId, roomId, robotSession, null);
|
GroupRoomBusiness.joinRoom(groupId, roomId, robotSession, null);
|
||||||
|
|
||||||
Thread.sleep(5000);
|
//非阻塞延迟替代Thread.sleep
|
||||||
|
scheduleDelay(() -> {
|
||||||
|
|
||||||
|
}, 5, TimeUnit.SECONDS);
|
||||||
|
|
||||||
params.del("groupId");
|
params.del("groupId");
|
||||||
params.del("roomId");
|
params.del("roomId");
|
||||||
|
|
@ -347,7 +353,10 @@ public class EXGameController extends GameController {
|
||||||
//先不放入映射 等确认加入成功后再放入
|
//先不放入映射 等确认加入成功后再放入
|
||||||
//robotRoomMapping.put(robotUser.getConnecId(), robotUser);
|
//robotRoomMapping.put(robotUser.getConnecId(), robotUser);
|
||||||
robotRoomMapping.remove(robotUser.getRobotId());
|
robotRoomMapping.remove(robotUser.getRobotId());
|
||||||
Thread.sleep(2000);
|
//非阻塞延迟替代Thread.sleep
|
||||||
|
scheduleDelay(() -> {
|
||||||
|
|
||||||
|
}, 2, TimeUnit.SECONDS);
|
||||||
params.putString("session", "{user}:" + robotId + "," + robotSession);
|
params.putString("session", "{user}:" + robotId + "," + robotSession);
|
||||||
|
|
||||||
//发送加入房间请求到game_mj_cs
|
//发送加入房间请求到game_mj_cs
|
||||||
|
|
@ -371,14 +380,21 @@ public class EXGameController extends GameController {
|
||||||
//添加超时检查机制
|
//添加超时检查机制
|
||||||
CompletableFuture.runAsync(() -> {
|
CompletableFuture.runAsync(() -> {
|
||||||
try {
|
try {
|
||||||
Thread.sleep(15000);
|
//定时任务替代Thread.sleep
|
||||||
//10秒后还没有建立映射关系 加入可能失败
|
scheduleDelay(() -> {
|
||||||
|
//15秒后还没有建立映射关系 加入可能失败
|
||||||
|
if (robotRoomMapping.get(robotUser.getConnecId()) == null) {
|
||||||
|
System.err.println("机器人{"+robotId+"}加入房间{"+roomId+"}超时,清理临时状态");
|
||||||
|
robotConnectionManager.disconnectFromGameServer(connecId);
|
||||||
|
}
|
||||||
|
}, 15, TimeUnit.SECONDS);
|
||||||
|
//15秒后还没有建立映射关系 加入可能失败
|
||||||
if (robotRoomMapping.get(robotUser.getConnecId()) == null) {
|
if (robotRoomMapping.get(robotUser.getConnecId()) == null) {
|
||||||
System.err.println("机器人{"+robotId+"}加入房间{"+roomId+"}超时,清理临时状态");
|
System.err.println("机器人{"+robotId+"}加入房间{"+roomId+"}超时,清理临时状态");
|
||||||
robotConnectionManager.disconnectFromGameServer(connecId);
|
robotConnectionManager.disconnectFromGameServer(connecId);
|
||||||
}
|
}
|
||||||
} catch (InterruptedException e) {
|
} catch (Exception e) {
|
||||||
Thread.currentThread().interrupt();
|
log.error("机器人加入房间超时", e);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
robotUser.setIntoRoomTime(robotConnectionManager.getTime());
|
robotUser.setIntoRoomTime(robotConnectionManager.getTime());
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,27 @@ public class EXMainServer extends MainServer{
|
||||||
public void onStart() {
|
public void onStart() {
|
||||||
super.onStart();
|
super.onStart();
|
||||||
|
|
||||||
|
//JVM关闭钩子
|
||||||
|
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
|
||||||
|
log.info("收到JVM关闭信号,开始优雅关闭...");
|
||||||
|
try {
|
||||||
|
//关闭所有机器人连接
|
||||||
|
for (Map.Entry<String, RobotUser> entry : robotRoomMapping.entrySet()) {
|
||||||
|
RobotUser robotUser = entry.getValue();
|
||||||
|
if (robotUser.getClient() != null && robotUser.getClient().isConnected()) {
|
||||||
|
robotConnectionManager.disconnectFromGameServer(robotUser.getConnecId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//关闭线程池
|
||||||
|
robot.mj.thread.ThreadPoolConfig.shutdown();
|
||||||
|
|
||||||
|
log.info("优雅关闭完成");
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("关闭过程中发生异常", e);
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
// 1. 先启动独立的事件处理线程(只启动一次)
|
// 1. 先启动独立的事件处理线程(只启动一次)
|
||||||
startNetEventThread();
|
startNetEventThread();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ import com.taurus.core.util.Logger;
|
||||||
import com.taurus.core.util.StringUtil;
|
import com.taurus.core.util.StringUtil;
|
||||||
import robot.mj.business.AccountBusiness;
|
import robot.mj.business.AccountBusiness;
|
||||||
import robot.mj.info.RobotUser;
|
import robot.mj.info.RobotUser;
|
||||||
|
import robot.mj.thread.ThreadPoolConfig;
|
||||||
import taurus.client.Message;
|
import taurus.client.Message;
|
||||||
import taurus.client.MessageResponse;
|
import taurus.client.MessageResponse;
|
||||||
import taurus.client.TaurusClient;
|
import taurus.client.TaurusClient;
|
||||||
|
|
@ -22,6 +23,10 @@ import taurus.util.ROBOTEventType;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.*;
|
import java.util.concurrent.*;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
|
import static robot.mj.thread.ThreadPoolConfig.getBusinessThreadPool;
|
||||||
|
import static robot.mj.thread.ThreadPoolConfig.scheduleDelay;
|
||||||
|
|
||||||
import static robot.mj.EXGameController.robotRoomMapping;
|
import static robot.mj.EXGameController.robotRoomMapping;
|
||||||
|
|
||||||
|
|
@ -292,14 +297,31 @@ public class RobotConnectionManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sleepTime(2000);
|
//非阻塞的延迟执行,增加更完善的异常处理
|
||||||
Map<Integer, List<Integer>> currentPlayerOutcardsMap = getPlayerOutcardsMap(connecId);
|
scheduleDelay(() -> {
|
||||||
Map<Integer, List<Integer>> currentPlayerchisMap = getPlayerchisMap(connecId);
|
try {
|
||||||
Map<Integer, List<Integer>> currentPlayerpengsMap = getPlayerpengsMap(connecId);
|
//重新获取当前实例,确保数据一致性
|
||||||
Map<Integer, List<Integer>> currentPlayermingsMap = getPlayermingsMap(connecId);
|
HuNanChangSha reconnectedInstance = getHuNanChangShaInstance(connecId);
|
||||||
Map<Integer, List<Integer>> currentPlayerzisMap = getPlayerzisMap(connecId);
|
Map<Integer, List<Integer>> currentPlayerOutcardsMap = getPlayerOutcardsMap(connecId);
|
||||||
|
Map<Integer, List<Integer>> currentPlayerchisMap = getPlayerchisMap(connecId);
|
||||||
|
Map<Integer, List<Integer>> currentPlayerpengsMap = getPlayerpengsMap(connecId);
|
||||||
|
Map<Integer, List<Integer>> currentPlayermingsMap = getPlayermingsMap(connecId);
|
||||||
|
Map<Integer, List<Integer>> currentPlayerzisMap = getPlayerzisMap(connecId);
|
||||||
|
|
||||||
currentInstance.outCard(client, currentPlayerOutcardsMap, currentPlayerchisMap, currentPlayerpengsMap, currentPlayermingsMap, currentPlayerzisMap);
|
reconnectedInstance.outCard(client, currentPlayerOutcardsMap, currentPlayerchisMap, currentPlayerpengsMap, currentPlayermingsMap, currentPlayerzisMap);
|
||||||
|
System.out.println("断线重连后成功执行出牌操作");
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("断线重连后执行出牌操作时发生异常", e);
|
||||||
|
//即使出牌失败,也要确保连接状态正确
|
||||||
|
try {
|
||||||
|
if (robotUser != null) {
|
||||||
|
robotUser.setStatus(ROBOTEventType.ROBOT_INTOROOM_READY);
|
||||||
|
}
|
||||||
|
} catch (Exception statusEx) {
|
||||||
|
log.error("更新机器人状态时发生异常", statusEx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, 2, TimeUnit.SECONDS);
|
||||||
} else {
|
} else {
|
||||||
System.err.println("警告:重连时未获取到手牌数据");
|
System.err.println("警告:重连时未获取到手牌数据");
|
||||||
}
|
}
|
||||||
|
|
@ -307,7 +329,7 @@ public class RobotConnectionManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}catch (Exception e) {
|
}catch (Exception e) {
|
||||||
e.printStackTrace();
|
log.error("机器人断线重连异常");
|
||||||
}
|
}
|
||||||
}else {
|
}else {
|
||||||
renconnect(robotUser);
|
renconnect(robotUser);
|
||||||
|
|
@ -481,68 +503,83 @@ public class RobotConnectionManager {
|
||||||
}
|
}
|
||||||
//2026.02.03修改 玩家加入房间
|
//2026.02.03修改 玩家加入房间
|
||||||
else if ("2001".equalsIgnoreCase(command)) {
|
else if ("2001".equalsIgnoreCase(command)) {
|
||||||
CompletableFuture.runAsync(() -> {
|
//直接使用定时任务替代Thread.sleep,避免嵌套异步调用
|
||||||
sleepTime(6000);
|
scheduleDelay(() -> {
|
||||||
|
Jedis jedis = Redis.use().getJedis();
|
||||||
|
try {
|
||||||
|
String roomKey = String.valueOf(robotUser.getCurrentRoomId());
|
||||||
|
|
||||||
String roomKey = String.valueOf(robotUser.getCurrentRoomId());
|
//查询该房间的玩家信息
|
||||||
|
String playersStr = jedis.hget("room:"+roomKey, "players");
|
||||||
|
if (playersStr != null && !playersStr.equals("[]")) {
|
||||||
|
String players = playersStr.substring(1, playersStr.length() - 1);
|
||||||
|
String[] playerIds = players.split(",");
|
||||||
|
|
||||||
//查询该房间的玩家信息
|
//判断只有当前机器人一个玩家
|
||||||
String playersStr = jedis0.hget("room:"+roomKey, "players");
|
if (playerIds.length == 1) {
|
||||||
if (!playersStr.equals("[]")) {
|
int playerId = Integer.parseInt(playerIds[0].trim());
|
||||||
String players = playersStr.substring(1, playersStr.length() - 1);
|
if (playerId == robotId) {
|
||||||
String[] playerIds = players.split(",");
|
//发送退出房间协议
|
||||||
|
ITObject params = TObject.newInstance();
|
||||||
//判断只有当前机器人一个玩家
|
client.send("1005", params, response -> {
|
||||||
if (playerIds.length == 1) {
|
EXGameController.removeRobotRoomInfo(String.valueOf(robotId));
|
||||||
int playerId = Integer.parseInt(playerIds[0].trim());
|
//更新机器人剩余数量
|
||||||
if (playerId == robotId) {
|
updateLeftoverRobot(robotId);
|
||||||
|
disconnectFromGameServer(connecId);
|
||||||
//发送退出房间协议
|
System.out.println("2001发送退出房间协议1005,robotId: {"+robotId+"}");
|
||||||
ITObject params = TObject.newInstance();
|
});
|
||||||
client.send("1005", params, response -> {
|
}
|
||||||
EXGameController.removeRobotRoomInfo(String.valueOf(robotId));
|
|
||||||
//更新机器人剩余数量
|
|
||||||
updateLeftoverRobot(robotId);
|
|
||||||
disconnectFromGameServer(connecId);
|
|
||||||
System.out.println("2002发送退出房间协议1005,robotId: {"+robotId+"}");
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("处理玩家加入房间检查时发生异常", e);
|
||||||
|
} finally {
|
||||||
|
// 确保Jedis连接关闭
|
||||||
|
if (jedis != null) {
|
||||||
|
jedis.close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
}, 6, TimeUnit.SECONDS);
|
||||||
System.out.println("玩家{"+ robotUser.getCurrentRoomId()+"}加入房间:"+ param);
|
System.out.println("玩家{"+ robotUser.getCurrentRoomId()+"}加入房间:"+ param);
|
||||||
}
|
}
|
||||||
//2026.02.03修改 玩家退出房间也要检查
|
//2026.02.03修改 玩家退出房间也要检查
|
||||||
else if ("2002".equalsIgnoreCase(command)) {
|
else if ("2002".equalsIgnoreCase(command)) {
|
||||||
CompletableFuture.runAsync(() -> {
|
//直接使用定时任务替代Thread.sleep,避免嵌套异步调用
|
||||||
sleepTime(6000);
|
scheduleDelay(() -> {
|
||||||
|
Jedis jedis = Redis.use().getJedis();
|
||||||
|
try {
|
||||||
|
String roomKey = String.valueOf(robotUser.getCurrentRoomId());
|
||||||
|
|
||||||
String roomKey = String.valueOf(robotUser.getCurrentRoomId());
|
//查询该房间的玩家信息
|
||||||
|
String playersStr = jedis.hget("room:"+roomKey, "players");
|
||||||
|
if (playersStr != null && !playersStr.equals("[]")) {
|
||||||
|
String players = playersStr.substring(1, playersStr.length() - 1);
|
||||||
|
String[] playerIds = players.split(",");
|
||||||
|
|
||||||
//查询该房间的玩家信息
|
//判断只有当前机器人一个玩家
|
||||||
String playersStr = jedis0.hget("room:"+roomKey, "players");
|
if (playerIds.length == 1) {
|
||||||
if (!playersStr.equals("[]")) {
|
int playerId = Integer.parseInt(playerIds[0].trim());
|
||||||
String players = playersStr.substring(1, playersStr.length() - 1);
|
if (playerId == robotId) {
|
||||||
String[] playerIds = players.split(",");
|
//发送退出房间协议
|
||||||
|
ITObject params = TObject.newInstance();
|
||||||
//判断只有当前机器人一个玩家
|
client.send("1005", params, response -> {
|
||||||
if (playerIds.length == 1) {
|
EXGameController.removeRobotRoomInfo(String.valueOf(robotId));
|
||||||
int playerId = Integer.parseInt(playerIds[0].trim());
|
//更新机器人剩余数量
|
||||||
if (playerId == robotId) {
|
updateLeftoverRobot(robotId);
|
||||||
|
disconnectFromGameServer(connecId);
|
||||||
//发送退出房间协议
|
System.out.println("2002发送退出房间协议1005,robotId: {"+robotId+"}");
|
||||||
ITObject params = TObject.newInstance();
|
});
|
||||||
client.send("1005", params, response -> {
|
}
|
||||||
EXGameController.removeRobotRoomInfo(String.valueOf(robotId));
|
|
||||||
//更新机器人剩余数量
|
|
||||||
updateLeftoverRobot(robotId);
|
|
||||||
disconnectFromGameServer(connecId);
|
|
||||||
System.out.println("2002发送退出房间协议1005,robotId: {"+robotId+"}");
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("处理玩家退出房间检查时发生异常", e);
|
||||||
|
} finally {
|
||||||
|
if (jedis != null) {
|
||||||
|
jedis.close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
}, 6, TimeUnit.SECONDS);
|
||||||
}
|
}
|
||||||
//2026.02.05修改 玩家解散房间
|
//2026.02.05修改 玩家解散房间
|
||||||
else if ("2005".equalsIgnoreCase(command)) {
|
else if ("2005".equalsIgnoreCase(command)) {
|
||||||
|
|
@ -559,49 +596,56 @@ public class RobotConnectionManager {
|
||||||
}
|
}
|
||||||
//2026.02.03修改 通过机器人房间映射直接获取房间信息
|
//2026.02.03修改 通过机器人房间映射直接获取房间信息
|
||||||
else if ("2009".equalsIgnoreCase(command)) {
|
else if ("2009".equalsIgnoreCase(command)) {
|
||||||
CompletableFuture.runAsync(() -> {
|
//直接使用定时任务替代Thread.sleep,避免嵌套异步调用
|
||||||
Integer paramRobotId = param.getInt("aid");
|
scheduleDelay(() -> {
|
||||||
sleepTime(6000);
|
Jedis localJedis = Redis.use().getJedis();
|
||||||
|
try {
|
||||||
|
Integer paramRobotId = param.getInt("aid");
|
||||||
|
if (robotUser != null) {
|
||||||
|
String roomKey = String.valueOf(robotUser.getCurrentRoomId());
|
||||||
|
|
||||||
if (robotUser != null) {
|
//查询该房间的玩家信息
|
||||||
String roomKey = String.valueOf(robotUser.getCurrentRoomId());
|
String playersStr = localJedis.hget(roomKey, "players");
|
||||||
|
if (playersStr != null && !playersStr.equals("[]")) {
|
||||||
|
String players = playersStr.substring(1, playersStr.length() - 1);
|
||||||
|
String[] playerIds = players.split(",");
|
||||||
|
|
||||||
//查询该房间的玩家信息
|
//判断只有当前机器人一个玩家
|
||||||
String playersStr = jedis0.hget(roomKey, "players");
|
if (playerIds.length == 1) {
|
||||||
if (!playersStr.equals("[]")) {
|
int playerId = Integer.parseInt(playerIds[0].trim());
|
||||||
String players = playersStr.substring(1, playersStr.length() - 1);
|
if (playerId == paramRobotId) {
|
||||||
String[] playerIds = players.split(",");
|
String gpid = localJedis.hget(roomKey, "gpid");
|
||||||
|
|
||||||
//判断只有当前机器人一个玩家
|
|
||||||
if (playerIds.length == 1) {
|
|
||||||
int playerId = Integer.parseInt(playerIds[0].trim());
|
|
||||||
if (playerId == paramRobotId) {
|
|
||||||
|
|
||||||
String gpid = jedis0.hget(roomKey, "gpid");
|
|
||||||
|
|
||||||
//更新机器人剩余数量
|
|
||||||
if (count != null && count.containsKey(Integer.parseInt(gpid))) {
|
|
||||||
Integer currentValue = count.get(Integer.parseInt(gpid));
|
|
||||||
if (currentValue > 0) {
|
|
||||||
count.put(Integer.parseInt(gpid), currentValue - 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//发送退出房间协议
|
|
||||||
ITObject params = TObject.newInstance();
|
|
||||||
client.send("1005", params, response -> {
|
|
||||||
EXGameController.removeRobotRoomInfo(String.valueOf(paramRobotId));
|
|
||||||
//断开连接
|
|
||||||
disconnectFromGameServer(connecId);
|
|
||||||
//更新机器人剩余数量
|
//更新机器人剩余数量
|
||||||
updateLeftoverRobot(paramRobotId);
|
if (count != null && count.containsKey(Integer.parseInt(gpid))) {
|
||||||
System.out.println("2009发送退出房间协议1005,robotId: {"+paramRobotId+"}");
|
Integer currentValue = count.get(Integer.parseInt(gpid));
|
||||||
});
|
if (currentValue > 0) {
|
||||||
|
count.put(Integer.parseInt(gpid), currentValue - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//发送退出房间协议
|
||||||
|
ITObject params = TObject.newInstance();
|
||||||
|
client.send("1005", params, response -> {
|
||||||
|
EXGameController.removeRobotRoomInfo(String.valueOf(paramRobotId));
|
||||||
|
//断开连接
|
||||||
|
disconnectFromGameServer(connecId);
|
||||||
|
//更新机器人剩余数量
|
||||||
|
updateLeftoverRobot(paramRobotId);
|
||||||
|
System.out.println("2009发送退出房间协议1005,robotId: {"+paramRobotId+"}");
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("处理机器人房间映射检查时发生异常", e);
|
||||||
|
} finally {
|
||||||
|
if (localJedis != null) {
|
||||||
|
localJedis.close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
}, 6, TimeUnit.SECONDS);
|
||||||
}
|
}
|
||||||
//结算
|
//结算
|
||||||
else if ("817".equalsIgnoreCase(command)) {
|
else if ("817".equalsIgnoreCase(command)) {
|
||||||
|
|
@ -624,9 +668,6 @@ public class RobotConnectionManager {
|
||||||
//更新机器人剩余数量
|
//更新机器人剩余数量
|
||||||
updateLeftoverRobot(Integer.parseInt(robotUser.getRobotId()));
|
updateLeftoverRobot(Integer.parseInt(robotUser.getRobotId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
sleepTime(1000);
|
|
||||||
|
|
||||||
ITObject params = TObject.newInstance();
|
ITObject params = TObject.newInstance();
|
||||||
params.putString("session", client.getSession());
|
params.putString("session", client.getSession());
|
||||||
client.send("1003", params, new ICallback<MessageResponse>() {
|
client.send("1003", params, new ICallback<MessageResponse>() {
|
||||||
|
|
@ -675,7 +716,7 @@ public class RobotConnectionManager {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new RuntimeException(e);
|
log.error("处理接收到的游戏协议");
|
||||||
} finally {
|
} finally {
|
||||||
jedis0.close();
|
jedis0.close();
|
||||||
jedis2.close();
|
jedis2.close();
|
||||||
|
|
@ -739,7 +780,7 @@ public class RobotConnectionManager {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new RuntimeException(e);
|
log.error("机器人登录异常");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -753,8 +794,8 @@ public class RobotConnectionManager {
|
||||||
robotUser.setIsconnect(client.isConnected());
|
robotUser.setIsconnect(client.isConnected());
|
||||||
try {
|
try {
|
||||||
Thread.sleep(1000);
|
Thread.sleep(1000);
|
||||||
} catch (InterruptedException e) {
|
} catch (Exception e) {
|
||||||
throw new RuntimeException(e);
|
log.error("连接游戏服务器时发生异常", e);
|
||||||
}
|
}
|
||||||
robotUser.setClient(client);
|
robotUser.setClient(client);
|
||||||
EXGameController.robotRoomMapping.put(robotUser.getCurrentRoomId()+"_"+robotUser.getRobotId(), robotUser);
|
EXGameController.robotRoomMapping.put(robotUser.getCurrentRoomId()+"_"+robotUser.getRobotId(), robotUser);
|
||||||
|
|
@ -771,8 +812,8 @@ public class RobotConnectionManager {
|
||||||
robotUser.setIsconnect(client.isConnected());
|
robotUser.setIsconnect(client.isConnected());
|
||||||
try {
|
try {
|
||||||
Thread.sleep(1000);
|
Thread.sleep(1000);
|
||||||
} catch (InterruptedException e) {
|
} catch (Exception e) {
|
||||||
throw new RuntimeException(e);
|
log.error("重新连接游戏服务器时发生异常", e);
|
||||||
}
|
}
|
||||||
robotUser.setClient(client);
|
robotUser.setClient(client);
|
||||||
EXGameController.robotRoomMapping.put(robotUser.getCurrentRoomId()+"_"+robotUser.getRobotId(), robotUser);
|
EXGameController.robotRoomMapping.put(robotUser.getCurrentRoomId()+"_"+robotUser.getRobotId(), robotUser);
|
||||||
|
|
@ -811,7 +852,7 @@ public class RobotConnectionManager {
|
||||||
//添加延迟
|
//添加延迟
|
||||||
Thread.sleep(time);
|
Thread.sleep(time);
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
e.printStackTrace();
|
System.out.println(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,12 +21,14 @@ import com.taurus.web.Controller;
|
||||||
import com.taurus.web.WebException;
|
import com.taurus.web.WebException;
|
||||||
import redis.clients.jedis.Jedis;
|
import redis.clients.jedis.Jedis;
|
||||||
|
|
||||||
|
import java.sql.SQLException;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
public class AccountBusiness extends Controller {
|
public class AccountBusiness extends Controller {
|
||||||
|
private static final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(AccountBusiness.class);
|
||||||
private static Logger logger = Logger.getLogger(AccountBusiness.class);
|
private static Logger logger = Logger.getLogger(AccountBusiness.class);
|
||||||
|
|
||||||
private ITObject fillLoginData(String session, int accountid) {
|
private ITObject fillLoginData(String session, int accountid) {
|
||||||
|
|
@ -101,7 +103,7 @@ public class AccountBusiness extends Controller {
|
||||||
if (StringUtil.isNotEmpty(idPwdBan))
|
if (StringUtil.isNotEmpty(idPwdBan))
|
||||||
{
|
{
|
||||||
logger.error("id:"+acc_bean.id+" ban login");
|
logger.error("id:"+acc_bean.id+" ban login");
|
||||||
throw new WebException(ErrorCode.BAN_LOGIN);
|
//throw new WebException(ErrorCode.BAN_LOGIN);
|
||||||
}
|
}
|
||||||
resData.putString("token", token);
|
resData.putString("token", token);
|
||||||
return resData;
|
return resData;
|
||||||
|
|
@ -116,7 +118,7 @@ public class AccountBusiness extends Controller {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public final ITObject idPasswordLogin(int id, String password) throws Exception {
|
public final ITObject idPasswordLogin(int id, String password) {
|
||||||
logger.info("id:" + id + " login");
|
logger.info("id:" + id + " login");
|
||||||
|
|
||||||
Jedis jedis0 = Redis.use("group1_db0").getJedis();
|
Jedis jedis0 = Redis.use("group1_db0").getJedis();
|
||||||
|
|
@ -145,12 +147,17 @@ public class AccountBusiness extends Controller {
|
||||||
if (StringUtil.isNotEmpty(idPwdBan)) {
|
if (StringUtil.isNotEmpty(idPwdBan)) {
|
||||||
System.out.println("进入了77777777777777777777");
|
System.out.println("进入了77777777777777777777");
|
||||||
logger.error("id:" + id + " ban login");
|
logger.error("id:" + id + " ban login");
|
||||||
throw new WebException(ErrorCode.BAN_LOGIN);
|
//throw new WebException(ErrorCode.BAN_LOGIN);
|
||||||
}
|
}
|
||||||
System.out.println("进入了9999999999999");
|
System.out.println("进入了9999999999999");
|
||||||
|
|
||||||
ITArray resultArray = DataBase.use().executeQueryByTArray(sql);
|
ITArray resultArray = null;
|
||||||
if (resultArray.size() == 0) {
|
try {
|
||||||
|
resultArray = DataBase.use().executeQueryByTArray(sql);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
log.error(e);
|
||||||
|
}
|
||||||
|
if (resultArray.size() == 0) {
|
||||||
if (Redis.use("group1_db0").exists(id + "_pwd_token")) {
|
if (Redis.use("group1_db0").exists(id + "_pwd_token")) {
|
||||||
Redis.use("group1_db0").incrBy(id + "_pwd_token", 1);
|
Redis.use("group1_db0").incrBy(id + "_pwd_token", 1);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -167,13 +174,13 @@ public class AccountBusiness extends Controller {
|
||||||
logger.error("pwd error count:" + count + " not login");
|
logger.error("pwd error count:" + count + " not login");
|
||||||
System.out.println("进入了00000000000");
|
System.out.println("进入了00000000000");
|
||||||
|
|
||||||
throw new WebException(ErrorCode._NO_SESSION);
|
//throw new WebException(ErrorCode._NO_SESSION);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
System.out.println("进入了111111111111");
|
System.out.println("进入了111111111111");
|
||||||
|
|
||||||
throw new WebException(ErrorCode._FAILED);
|
//throw new WebException(ErrorCode._FAILED);
|
||||||
}
|
}
|
||||||
|
|
||||||
ITObject userData = resultArray.getTObject(0);
|
ITObject userData = resultArray.getTObject(0);
|
||||||
|
|
|
||||||
|
|
@ -13,11 +13,11 @@ import taurus.client.TaurusClient;
|
||||||
import taurus.util.*;
|
import taurus.util.*;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.CompletableFuture;
|
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import com.google.gson.reflect.TypeToken;
|
import com.google.gson.reflect.TypeToken;
|
||||||
|
|
||||||
|
import static robot.mj.thread.ThreadPoolConfig.getBusinessThreadPool;
|
||||||
|
|
||||||
public class HuNanChangSha {
|
public class HuNanChangSha {
|
||||||
|
|
||||||
|
|
@ -312,6 +312,28 @@ public class HuNanChangSha {
|
||||||
changShachuguopai.addAll(outCard);
|
changShachuguopai.addAll(outCard);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 延迟执行吃碰胡动作,增加自然的停顿效果
|
||||||
|
* @param client 客户端连接
|
||||||
|
* @param params 动作参数
|
||||||
|
*/
|
||||||
|
private void delayedActionCard(TaurusClient client, ITObject params, String actionName) {
|
||||||
|
//使用线程池执行延迟动作
|
||||||
|
getBusinessThreadPool().execute(() -> {
|
||||||
|
try {
|
||||||
|
int delaySeconds = 1 + new Random().nextInt(2);
|
||||||
|
System.out.println("执行" + actionName + "动作,延迟" + delaySeconds + "秒");
|
||||||
|
Thread.sleep(delaySeconds * 1000);
|
||||||
|
|
||||||
|
client.send("612", params, response -> {
|
||||||
|
System.out.println(actionName + "动作发送完成");
|
||||||
|
});
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.err.println("执行" + actionName + "动作时发生异常: " + e.getMessage());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 处理 吃,碰,杠,补,胡
|
* 处理 吃,碰,杠,补,胡
|
||||||
*
|
*
|
||||||
|
|
@ -393,8 +415,8 @@ public class HuNanChangSha {
|
||||||
params.putString("session", session + "," + token);
|
params.putString("session", session + "," + token);
|
||||||
params.putInt("qi", 0);
|
params.putInt("qi", 0);
|
||||||
params.putInt("id", id);
|
params.putInt("id", id);
|
||||||
client.send("612", params, response -> {
|
//使用延迟方法
|
||||||
});
|
delayedActionCard(client, params, "胡牌");
|
||||||
return "胡牌";
|
return "胡牌";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -429,8 +451,7 @@ public class HuNanChangSha {
|
||||||
params.putString("session", session + "," + token);
|
params.putString("session", session + "," + token);
|
||||||
params.putInt("qi", 0);
|
params.putInt("qi", 0);
|
||||||
params.putInt("id", 0);
|
params.putInt("id", 0);
|
||||||
client.send("612", params, response -> {
|
delayedActionCard(client, params, "不开杠");
|
||||||
});
|
|
||||||
return "不开杠";
|
return "不开杠";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -438,15 +459,13 @@ public class HuNanChangSha {
|
||||||
params.putString("session", session + "," + token);
|
params.putString("session", session + "," + token);
|
||||||
params.putInt("qi", 0);
|
params.putInt("qi", 0);
|
||||||
params.putInt("id", id);
|
params.putInt("id", id);
|
||||||
client.send("612", params, response -> {
|
delayedActionCard(client, params, "开杠");
|
||||||
});
|
|
||||||
return "开杠";
|
return "开杠";
|
||||||
} else {
|
} else {
|
||||||
params.putString("session", session + "," + token);
|
params.putString("session", session + "," + token);
|
||||||
params.putInt("qi", 0);
|
params.putInt("qi", 0);
|
||||||
params.putInt("id", 0);
|
params.putInt("id", 0);
|
||||||
client.send("612", params, response -> {
|
delayedActionCard(client, params, "不开杠");
|
||||||
});
|
|
||||||
return "不开杠";
|
return "不开杠";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -468,8 +487,7 @@ public class HuNanChangSha {
|
||||||
params.putString("session", session + "," + token);
|
params.putString("session", session + "," + token);
|
||||||
params.putInt("qi", 0);
|
params.putInt("qi", 0);
|
||||||
params.putInt("id", 0);
|
params.putInt("id", 0);
|
||||||
client.send("612", params, response -> {
|
delayedActionCard(client, params, "不开杠");
|
||||||
});
|
|
||||||
return "不开杠";
|
return "不开杠";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -477,15 +495,13 @@ public class HuNanChangSha {
|
||||||
params.putString("session", session + "," + token);
|
params.putString("session", session + "," + token);
|
||||||
params.putInt("qi", 0);
|
params.putInt("qi", 0);
|
||||||
params.putInt("id", id);
|
params.putInt("id", id);
|
||||||
client.send("612", params, response -> {
|
delayedActionCard(client, params, "开杠");
|
||||||
});
|
|
||||||
return "开杠";
|
return "开杠";
|
||||||
} else {
|
} else {
|
||||||
params.putString("session", session + "," + token);
|
params.putString("session", session + "," + token);
|
||||||
params.putInt("qi", 0);
|
params.putInt("qi", 0);
|
||||||
params.putInt("id", 0);
|
params.putInt("id", 0);
|
||||||
client.send("612", params, response -> {
|
delayedActionCard(client, params, "不开杠");
|
||||||
});
|
|
||||||
return "不开杠";
|
return "不开杠";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -505,24 +521,22 @@ public class HuNanChangSha {
|
||||||
params.putString("session", session + "," + token);
|
params.putString("session", session + "," + token);
|
||||||
params.putInt("qi", 0);
|
params.putInt("qi", 0);
|
||||||
params.putInt("id", 0);
|
params.putInt("id", 0);
|
||||||
client.send("612", params, response -> {
|
delayedActionCard(client, params, "不开杠");
|
||||||
});
|
|
||||||
return "不开杠";
|
return "不开杠";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Util.removeCard(changShaCardInhand, card, 1);
|
Util.removeCard(changShaCardInhand, card, 1);
|
||||||
params.putString("session", session + "," + token);
|
params.putString("session", session + "," + token);
|
||||||
params.putInt("qi", 0);
|
params.putInt("qi", 0);
|
||||||
params.putInt("id", id);
|
params.putInt("id", id);
|
||||||
client.send("612", params, response -> {
|
delayedActionCard(client, params, "开杠");
|
||||||
});
|
|
||||||
return "开杠";
|
return "开杠";
|
||||||
} else {
|
} else {
|
||||||
params.putString("session", session + "," + token);
|
params.putString("session", session + "," + token);
|
||||||
params.putInt("qi", 0);
|
params.putInt("qi", 0);
|
||||||
params.putInt("id", 0);
|
params.putInt("id", 0);
|
||||||
client.send("612", params, response -> {
|
delayedActionCard(client, params, "不开杠");
|
||||||
});
|
|
||||||
return "不开杠";
|
return "不开杠";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -560,8 +574,8 @@ public class HuNanChangSha {
|
||||||
params.putString("session", session + "," + token);
|
params.putString("session", session + "," + token);
|
||||||
params.putInt("qi", 0);
|
params.putInt("qi", 0);
|
||||||
params.putInt("id", id);
|
params.putInt("id", id);
|
||||||
client.send("612", params, response -> {
|
//使用延迟动作方法
|
||||||
});
|
delayedActionCard(client, params, "胡牌");
|
||||||
return "胡牌";
|
return "胡牌";
|
||||||
}
|
}
|
||||||
//对应的数据
|
//对应的数据
|
||||||
|
|
@ -599,14 +613,14 @@ public class HuNanChangSha {
|
||||||
params.putString("session", session + "," + token);
|
params.putString("session", session + "," + token);
|
||||||
params.putInt("qi", 0);
|
params.putInt("qi", 0);
|
||||||
params.putInt("id", 0);
|
params.putInt("id", 0);
|
||||||
client.send("612", params, response -> {
|
delayedActionCard(client, params, "");
|
||||||
});
|
|
||||||
return null;
|
return null;
|
||||||
} else {
|
} else {
|
||||||
//获取
|
//获取
|
||||||
|
ITObject tmp = null;
|
||||||
for (Map.Entry<Integer, ITObject> entry : idObject.entrySet()) {
|
for (Map.Entry<Integer, ITObject> entry : idObject.entrySet()) {
|
||||||
if (entry.getKey() == changeid) {
|
if (entry.getKey() == changeid) {
|
||||||
ITObject tmp = entry.getValue();
|
tmp = entry.getValue();
|
||||||
System.out.println("tmp ++++++++++= " + tmp);
|
System.out.println("tmp ++++++++++= " + tmp);
|
||||||
if (tmp.getInt("type") == 2) {
|
if (tmp.getInt("type") == 2) {
|
||||||
//碰
|
//碰
|
||||||
|
|
@ -635,9 +649,11 @@ public class HuNanChangSha {
|
||||||
params.putString("session", session + "," + token);
|
params.putString("session", session + "," + token);
|
||||||
params.putInt("qi", 0);
|
params.putInt("qi", 0);
|
||||||
params.putInt("id", changeid);
|
params.putInt("id", changeid);
|
||||||
client.send("612", params, response -> {
|
//使用延迟动作方法
|
||||||
});
|
String actionName = (tmp.getInt("type") == 2) ? "碰牌" : "吃牌";
|
||||||
|
delayedActionCard(client, params, actionName);
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -678,8 +694,7 @@ public class HuNanChangSha {
|
||||||
params.putString("session", session + "," + token);
|
params.putString("session", session + "," + token);
|
||||||
params.putInt("qi", 0);
|
params.putInt("qi", 0);
|
||||||
params.putInt("id", 0);
|
params.putInt("id", 0);
|
||||||
client.send("612", params, response -> {
|
delayedActionCard(client, params, "");
|
||||||
});
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
//去一张下听?
|
//去一张下听?
|
||||||
|
|
@ -691,8 +706,7 @@ public class HuNanChangSha {
|
||||||
params.putString("session", session + "," + token);
|
params.putString("session", session + "," + token);
|
||||||
params.putInt("qi", 0);
|
params.putInt("qi", 0);
|
||||||
params.putInt("id", 0);
|
params.putInt("id", 0);
|
||||||
client.send("612", params, response -> {
|
delayedActionCard(client, params, "补牌");
|
||||||
});
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -706,8 +720,7 @@ public class HuNanChangSha {
|
||||||
params.putString("session", session + "," + token);
|
params.putString("session", session + "," + token);
|
||||||
params.putInt("qi", 0);
|
params.putInt("qi", 0);
|
||||||
params.putInt("id", 0);
|
params.putInt("id", 0);
|
||||||
client.send("612", params, response -> {
|
delayedActionCard(client, params, "");
|
||||||
});
|
|
||||||
return null;
|
return null;
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
|
@ -718,9 +731,8 @@ public class HuNanChangSha {
|
||||||
params.putString("session", session + "," + token);
|
params.putString("session", session + "," + token);
|
||||||
params.putInt("qi", 0);
|
params.putInt("qi", 0);
|
||||||
params.putInt("id", 0);
|
params.putInt("id", 0);
|
||||||
client.send("612", params, response -> {
|
delayedActionCard(client, params, "不开杠");
|
||||||
});
|
return "不开杠";
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
System.out.println("补");
|
System.out.println("补");
|
||||||
|
|
@ -750,8 +762,7 @@ public class HuNanChangSha {
|
||||||
gangdepai.add(card);
|
gangdepai.add(card);
|
||||||
gangdepai.add(card);
|
gangdepai.add(card);
|
||||||
}
|
}
|
||||||
client.send("612", params, response -> {
|
delayedActionCard(client, params, "");
|
||||||
});
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -781,8 +792,7 @@ public class HuNanChangSha {
|
||||||
gangdepai.add(card);
|
gangdepai.add(card);
|
||||||
gangdepai.add(card);
|
gangdepai.add(card);
|
||||||
}
|
}
|
||||||
client.send("612", params, response -> {
|
delayedActionCard(client, params, "补牌");
|
||||||
});
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -791,8 +801,7 @@ public class HuNanChangSha {
|
||||||
params.putString("session", session + "," + token);
|
params.putString("session", session + "," + token);
|
||||||
params.putInt("qi", 0);
|
params.putInt("qi", 0);
|
||||||
params.putInt("id", 0);
|
params.putInt("id", 0);
|
||||||
client.send("612", params, response -> {
|
delayedActionCard(client, params, "默认动作");
|
||||||
});
|
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
@ -873,7 +882,8 @@ public class HuNanChangSha {
|
||||||
System.out.println("打过后的手牌 +++ " + changShaCardInhand);
|
System.out.println("打过后的手牌 +++ " + changShaCardInhand);
|
||||||
params.putString("session", session + "," + token);
|
params.putString("session", session + "," + token);
|
||||||
|
|
||||||
CompletableFuture.runAsync(() -> {
|
//使用线程池替代CompletableFuture.runAsync + Thread.sleep
|
||||||
|
getBusinessThreadPool().execute(() -> {
|
||||||
try {
|
try {
|
||||||
int ot = new Random().nextInt(4);
|
int ot = new Random().nextInt(4);
|
||||||
Thread.sleep(ot*1000);
|
Thread.sleep(ot*1000);
|
||||||
|
|
@ -882,7 +892,6 @@ public class HuNanChangSha {
|
||||||
});
|
});
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
System.out.println("Thread error");
|
System.out.println("Thread error");
|
||||||
//Thread.currentThread().interrupt();
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,106 @@
|
||||||
|
package robot.mj.thread;
|
||||||
|
|
||||||
|
import java.util.concurrent.*;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 线程池配置类
|
||||||
|
*/
|
||||||
|
public class ThreadPoolConfig {
|
||||||
|
|
||||||
|
// 优化后的线程池配置:针对机器人场景优化
|
||||||
|
private static final ExecutorService BUSINESS_THREAD_POOL =
|
||||||
|
new ThreadPoolExecutor(
|
||||||
|
10, // 核心线程数 - 减少核心线程数
|
||||||
|
50, // 最大线程数 - 降低最大线程数
|
||||||
|
30, // 空闲线程存活时间 - 缩短存活时间
|
||||||
|
TimeUnit.SECONDS,
|
||||||
|
new LinkedBlockingQueue<>(10000), // 增大队列容量,减少拒绝任务
|
||||||
|
new ThreadFactory() {
|
||||||
|
private final AtomicInteger threadNumber = new AtomicInteger(1);
|
||||||
|
@Override
|
||||||
|
public Thread newThread(Runnable r) {
|
||||||
|
Thread t = new Thread(r, "RobotBusinessThread-" + threadNumber.getAndIncrement());
|
||||||
|
t.setDaemon(true);
|
||||||
|
t.setPriority(Thread.NORM_PRIORITY - 2); // 进一步降低线程优先级
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
new ThreadPoolExecutor.CallerRunsPolicy() // 拒绝策略:由调用线程执行
|
||||||
|
);
|
||||||
|
|
||||||
|
// 添加定时任务线程池,专门处理延迟操作
|
||||||
|
private static final ScheduledExecutorService SCHEDULED_EXECUTOR_SERVICE =
|
||||||
|
Executors.newScheduledThreadPool(4, new ThreadFactory() {
|
||||||
|
private final AtomicInteger threadNumber = new AtomicInteger(1);
|
||||||
|
@Override
|
||||||
|
public Thread newThread(Runnable r) {
|
||||||
|
Thread t = new Thread(r, "RobotScheduledThread-" + threadNumber.getAndIncrement());
|
||||||
|
t.setDaemon(true);
|
||||||
|
t.setPriority(Thread.NORM_PRIORITY - 2);
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
public static ExecutorService getBusinessThreadPool() {
|
||||||
|
return BUSINESS_THREAD_POOL;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ScheduledExecutorService getScheduledExecutorService() {
|
||||||
|
return SCHEDULED_EXECUTOR_SERVICE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行延迟任务,替代Thread.sleep
|
||||||
|
*/
|
||||||
|
public static void scheduleDelay(Runnable task, long delay, TimeUnit unit) {
|
||||||
|
System.out.println("提交延迟任务: 延迟" + delay + " " + unit + ", 当前时间: " + System.currentTimeMillis());
|
||||||
|
SCHEDULED_EXECUTOR_SERVICE.schedule(() -> {
|
||||||
|
try {
|
||||||
|
System.out.println("执行延迟任务开始: 当前时间: " + System.currentTimeMillis());
|
||||||
|
task.run();
|
||||||
|
System.out.println("执行延迟任务完成: 当前时间: " + System.currentTimeMillis());
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.err.println("延迟任务执行异常: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}, delay, unit);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行周期性任务
|
||||||
|
*/
|
||||||
|
public static void scheduleAtFixedRate(Runnable task, long initialDelay, long period, TimeUnit unit) {
|
||||||
|
SCHEDULED_EXECUTOR_SERVICE.scheduleAtFixedRate(task, initialDelay, period, unit);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 优雅关闭线程池,释放资源
|
||||||
|
*/
|
||||||
|
public static void shutdown() {
|
||||||
|
System.out.println("开始关闭线程池...");
|
||||||
|
|
||||||
|
// 关闭定时任务线程池
|
||||||
|
SCHEDULED_EXECUTOR_SERVICE.shutdown();
|
||||||
|
try {
|
||||||
|
if (!SCHEDULED_EXECUTOR_SERVICE.awaitTermination(5, TimeUnit.SECONDS)) {
|
||||||
|
SCHEDULED_EXECUTOR_SERVICE.shutdownNow();
|
||||||
|
}
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
SCHEDULED_EXECUTOR_SERVICE.shutdownNow();
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 关闭业务线程池
|
||||||
|
BUSINESS_THREAD_POOL.shutdown();
|
||||||
|
try {
|
||||||
|
if (!BUSINESS_THREAD_POOL.awaitTermination(10, TimeUnit.SECONDS)) {
|
||||||
|
BUSINESS_THREAD_POOL.shutdownNow();
|
||||||
|
}
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
BUSINESS_THREAD_POOL.shutdownNow();
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println("线程池关闭完成");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -23,7 +23,7 @@ public class ChangshaWinSplitCard {
|
||||||
// 检测不带精湖
|
// 检测不带精湖
|
||||||
public static int checkNormalHu(List<Integer> cardInHand, Map<String, Object> map) {
|
public static int checkNormalHu(List<Integer> cardInHand, Map<String, Object> map) {
|
||||||
if (cardInHand == null || cardInHand.isEmpty()) {
|
if (cardInHand == null || cardInHand.isEmpty()) {
|
||||||
throw new IllegalArgumentException("手牌不能为空");
|
//throw new IllegalArgumentException("手牌不能为空");
|
||||||
}
|
}
|
||||||
|
|
||||||
String info = "";
|
String info = "";
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ public class ai {
|
||||||
public int findBestDiscard(PlayerState state) {
|
public int findBestDiscard(PlayerState state) {
|
||||||
//参数验证
|
//参数验证
|
||||||
if (state == null || state.handCards == null) {
|
if (state == null || state.handCards == null) {
|
||||||
throw new IllegalArgumentException("玩家状态和手牌不能为空");
|
//throw new IllegalArgumentException("玩家状态和手牌不能为空");
|
||||||
}
|
}
|
||||||
System.out.println("\n=== 长沙麻将AI出牌分析 ===");
|
System.out.println("\n=== 长沙麻将AI出牌分析 ===");
|
||||||
System.out.println("手牌(" + state.handCards.size() + "张): " + this.formatCards(state.handCards));
|
System.out.println("手牌(" + state.handCards.size() + "张): " + this.formatCards(state.handCards));
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue