红中添加清理的资源代码

master
zhouwei 2026-02-27 19:06:59 +08:00
parent f9bae0eff6
commit 0c1cee78c5
18 changed files with 332 additions and 82 deletions

View File

@ -12,6 +12,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import redis.clients.jedis.Jedis; import redis.clients.jedis.Jedis;
import robot.mj.info.RobotUser; import robot.mj.info.RobotUser;
import robot.mj.thread.ThreadPoolConfig;
import taurus.client.TaurusClient; import taurus.client.TaurusClient;
import taurus.client.business.GroupRoomBusiness; import taurus.client.business.GroupRoomBusiness;
import taurus.util.ROBOTEventType; import taurus.util.ROBOTEventType;
@ -34,6 +35,12 @@ public class EXGameController extends GameController {
//机器人房间 //机器人房间
protected static final Map<String, RobotUser> robotRoomMapping = new ConcurrentHashMap<>(); protected static final Map<String, RobotUser> robotRoomMapping = new ConcurrentHashMap<>();
//记录最近访问时间
private static final Map<String, Long> lastAccessTime = new ConcurrentHashMap<>();
//设置连接超时时间5分钟
private static final long CONNECTION_TIMEOUT = 5 * 60 * 1000;
public EXGameController() { public EXGameController() {
super(); super();
log.info("红中麻将游戏控制器已初始化"); log.info("红中麻将游戏控制器已初始化");
@ -225,31 +232,7 @@ public class EXGameController extends GameController {
int robotId = params.getInt("robotid"); int robotId = params.getInt("robotid");
String roomId = params.getString("roomid"); String roomId = params.getString("roomid");
int groupId = params.getInt("groupid"); int groupId = params.getInt("groupid");
//防止玩家操作同一房间 导致其他机器人加入
List<RobotUser> robotUsers = getRobotUsersByRoomId(Integer.parseInt(roomId));
if (!robotUsers.isEmpty()) {
synchronized (robotUsers) {
RobotUser robotUser = robotUsers.get(0);
if (robotId != Integer.parseInt(robotUser.getRobotId())) {
System.err.println("房间{"+ roomId +"}中已有机器人{"+robotUser.getRobotId()+"},当前机器人{"+robotId+"}不执行加入逻辑");
return;
}
}
}
System.err.println("225开始进房间: "+"room:"+ roomId +"robot:"+robotId);
//加入房间
joinRoomCommon(robotId, roomId, groupId, params);
System.err.println("225已进入房间准备成功: "+"room:"+ roomId +"robot:"+robotId);
}
/**
* web_group
*/
@ActionKey(value = Config.WEB_GROUP_ACTIVE_RECONNECT, validate = GameInterceptor.NOT_PLAYER)
public void webGroupActive(Session session, ITObject params, int gid) {
int robotId = params.getInt("robotid");
String roomId = params.getString("roomid");
//检查Redis中该房间是否真的包含当前机器人 //检查Redis中该房间是否真的包含当前机器人
if (!checkRobotInRoomRedis(roomId, String.valueOf(robotId))) { if (!checkRobotInRoomRedis(roomId, String.valueOf(robotId))) {
//Redis中不存在该机器人 清理本地可能的错误映射 //Redis中不存在该机器人 清理本地可能的错误映射
@ -278,6 +261,19 @@ public class EXGameController extends GameController {
} }
} }
} }
System.err.println("225开始进房间: "+"room:"+ roomId +"robot:"+robotId);
//加入房间
joinRoomCommon(robotId, roomId, groupId, params);
System.err.println("225已进入房间准备成功: "+"room:"+ roomId +"robot:"+robotId);
}
/**
* web_group
*/
@ActionKey(value = Config.WEB_GROUP_ACTIVE_RECONNECT, validate = GameInterceptor.NOT_PLAYER)
public void webGroupActive(Session session, ITObject params, int gid) {
int robotId = params.getInt("robotid");
String roomId = params.getString("roomid");
System.err.println("226开始进房间: " + "room:" + roomId + "robot:" + robotId); System.err.println("226开始进房间: " + "room:" + roomId + "robot:" + robotId);
//加入房间 //加入房间
joinRoomCommon(params.getInt("robotid"), params.getString("roomid"), params.getInt("groupid"), params); joinRoomCommon(params.getInt("robotid"), params.getString("roomid"), params.getInt("groupid"), params);
@ -390,7 +386,7 @@ public class EXGameController extends GameController {
} catch (InterruptedException e) { } catch (InterruptedException e) {
log.error("加入房间超时异常"); log.error("加入房间超时异常");
} }
}); }, ThreadPoolConfig.getBusinessThreadPool());//指定自定义线程池
robotUser.setIntoRoomTime(robotConnectionManager.getTime()); robotUser.setIntoRoomTime(robotConnectionManager.getTime());
System.err.println("已进入房间准备成功: " + robotUser.getConnecId()); System.err.println("已进入房间准备成功: " + robotUser.getConnecId());
} catch (Exception e) { } catch (Exception e) {
@ -438,7 +434,51 @@ public class EXGameController extends GameController {
* ID * ID
*/ */
public static void removeRobotRoomInfo(String robotId) { public static void removeRobotRoomInfo(String robotId) {
robotRoomMapping.remove(robotId); RobotUser removedUser = robotRoomMapping.remove(robotId);
lastAccessTime.remove(robotId);
// 如果有连接ID也一并清理
if (removedUser != null && removedUser.getConnecId() != null) {
robotRoomMapping.remove(removedUser.getConnecId());
lastAccessTime.remove(removedUser.getConnecId());
}
System.out.println("清理机器人房间信息: " + robotId);
}
/**
* 访
*/
public static void updateLastAccessTime(String connecId) {
lastAccessTime.put(connecId, System.currentTimeMillis());
}
/**
*
*/
public static void cleanupExpiredConnections() {
long currentTime = System.currentTimeMillis();
List<String> expiredConnections = new ArrayList<>();
for (Map.Entry<String, Long> entry : lastAccessTime.entrySet()) {
if (currentTime - entry.getValue() > CONNECTION_TIMEOUT) {
expiredConnections.add(entry.getKey());
}
}
for (String connecId : expiredConnections) {
RobotUser robotUser = robotRoomMapping.get(connecId);
if (robotUser != null) {
System.out.println("清理超时连接: " + connecId + ", 机器人ID: " + robotUser.getRobotId());
robotConnectionManager.disconnectFromGameServer(connecId);
}
robotRoomMapping.remove(connecId);
lastAccessTime.remove(connecId);
}
if (!expiredConnections.isEmpty()) {
System.out.println("本次清理了 " + expiredConnections.size() + " 个超时连接");
}
} }
/** /**

View File

@ -11,6 +11,8 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import redis.clients.jedis.Jedis; import redis.clients.jedis.Jedis;
import robot.mj.info.RobotUser; import robot.mj.info.RobotUser;
import robot.mj.thread.ResourceCleanupUtil;
import robot.mj.thread.ThreadPoolConfig;
import taurus.client.NetManager; import taurus.client.NetManager;
import static robot.mj.EXGameController.robotRoomMapping; import static robot.mj.EXGameController.robotRoomMapping;
@ -28,10 +30,34 @@ 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();
// 2. 启动连接检查定时任务 // 2. 启动资源清理定时任务
startResourceCleanupScheduler();
// 3. 启动连接检查定时任务
//startConnectionCheckScheduler(); //startConnectionCheckScheduler();
//测试 //测试
Jedis jedis2 = Redis.use("group1_db2").getJedis(); Jedis jedis2 = Redis.use("group1_db2").getJedis();
@ -63,6 +89,7 @@ public class EXMainServer extends MainServer{
//5、干活 //5、干活
log.info("红中麻将机器人服务器已启动"); log.info("红中麻将机器人服务器已启动");
log.info("服务器将监听端口 {} 用于接收robot_mgr管理协议", gameSetting.port); log.info("服务器将监听端口 {} 用于接收robot_mgr管理协议", gameSetting.port);
System.out.println("当前线程池配置: " + ThreadPoolConfig.getThreadPoolStatus());
jedis2.close(); jedis2.close();
} }
@ -87,7 +114,35 @@ public class EXMainServer extends MainServer{
eventThread.start(); eventThread.start();
} }
/**
*
*/
private void startResourceCleanupScheduler() {
Thread cleanupThread = new Thread(() -> {
while (true) {
try {
//每30秒执行一次资源清理
Thread.sleep(30000);
ResourceCleanupUtil.performCleanup();
System.out.println("线程池状态: " + ThreadPoolConfig.getThreadPoolStatus());
} catch (InterruptedException e) {
break;
} catch (Exception e) {
System.err.println("资源清理任务异常: " + e.getMessage());
// 发生异常时尝试清理
try {
ResourceCleanupUtil.performCleanup();
} catch (Exception cleanupEx) {
System.err.println("异常清理也失败: " + cleanupEx.getMessage());
}
}
}
}, "ResourceCleanupThread");
cleanupThread.setDaemon(true);
cleanupThread.start();
System.out.println("资源清理定时任务已启动");
}
@Override @Override
public Room newRoom(String roomid, Map<String, String> redis_room_map) { public Room newRoom(String roomid, Map<String, String> redis_room_map) {

View File

@ -18,6 +18,7 @@ import taurus.client.MessageResponse;
import taurus.client.TaurusClient; import taurus.client.TaurusClient;
import taurus.client.SocketCode; import taurus.client.SocketCode;
import redis.clients.jedis.Jedis; import redis.clients.jedis.Jedis;
import taurus.util.ROBOTEventType;
import java.util.*; import java.util.*;
import java.util.concurrent.*; import java.util.concurrent.*;
@ -32,6 +33,15 @@ public class RobotConnectionManager {
private static final Map<String, HuNanHongZhong> huNanHongZhongInstances = new ConcurrentHashMap<>(); private static final Map<String, HuNanHongZhong> huNanHongZhongInstances = new ConcurrentHashMap<>();
private static final Logger log = Logger.getLogger(RobotConnectionManager.class); private static final Logger log = Logger.getLogger(RobotConnectionManager.class);
//记录活跃连接 用于资源清理判断
private static final Set<String> activeConnections = ConcurrentHashMap.newKeySet();
//记录连接创建时间
private static final Map<String, Long> connectionCreationTime = new ConcurrentHashMap<>();
//连接最大生存时间5分钟
private static final long MAX_CONNECTION_LIFETIME = 5 * 60 * 1000;
private final EXGameController exGameController; private final EXGameController exGameController;
private final String host= Config.GAME_SERVER_HOST; private final String host= Config.GAME_SERVER_HOST;
@ -46,6 +56,13 @@ public class RobotConnectionManager {
* *
*/ */
private HuNanHongZhong getHuNanHongZhongInstance(String connecId) { private HuNanHongZhong getHuNanHongZhongInstance(String connecId) {
//标记连接为活跃状态
activeConnections.add(connecId);
connectionCreationTime.put(connecId, System.currentTimeMillis());
//定期清理过期连接
cleanupExpiredInstances();
HuNanHongZhong existingInstance = huNanHongZhongInstances.get(connecId); HuNanHongZhong existingInstance = huNanHongZhongInstances.get(connecId);
if (existingInstance != null) { if (existingInstance != null) {
return existingInstance; return existingInstance;
@ -101,6 +118,10 @@ public class RobotConnectionManager {
System.out.println("开始主动断开连接: {"+connecId+"}"); System.out.println("开始主动断开连接: {"+connecId+"}");
RobotUser robotUser = robotRoomMapping.remove(connecId); RobotUser robotUser = robotRoomMapping.remove(connecId);
//标记连接为非活跃
activeConnections.remove(connecId);
connectionCreationTime.remove(connecId);
//清理连接数据 //清理连接数据
if (connecId != null) { if (connecId != null) {
HuNanHongZhong.removeFromRedis(connecId); HuNanHongZhong.removeFromRedis(connecId);
@ -129,6 +150,34 @@ public class RobotConnectionManager {
} else { } else {
System.out.println("客户端连接不存在: {"+connecId+"}"); System.out.println("客户端连接不存在: {"+connecId+"}");
} }
//同时清理机器人房间映射
EXGameController.removeRobotRoomInfo(robotUser.getRobotId());
}
}
/**
*
*/
private void cleanupExpiredInstances() {
long currentTime = System.currentTimeMillis();
List<String> expiredConnections = new ArrayList<>();
//检查连接生存时间
for (Map.Entry<String, Long> entry : connectionCreationTime.entrySet()) {
if (currentTime - entry.getValue() > MAX_CONNECTION_LIFETIME) {
expiredConnections.add(entry.getKey());
}
}
//清理过期连接
for (String connecId : expiredConnections) {
System.out.println("清理过期连接实例: " + connecId);
disconnectFromGameServer(connecId);
}
if (!expiredConnections.isEmpty()) {
System.out.println("本次清理了 " + expiredConnections.size() + " 个过期连接实例");
} }
} }
@ -253,8 +302,25 @@ public class RobotConnectionManager {
} }
} }
sleepTime(2000); /*sleepTime(2000);
currentInstance.outCard(client); currentInstance.outCard(client);*/
//非阻塞的延迟执行,增加更完善的异常处理
scheduleDelay(() -> {
try {
currentInstance.outCard(client);
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("警告:重连时未获取到手牌数据");
} }
@ -274,6 +340,15 @@ public class RobotConnectionManager {
*/ */
private void handleProtocol(String command, Message message, TaurusClient client, String connecId) { private void handleProtocol(String command, Message message, TaurusClient client, String connecId) {
RobotUser robotUser = robotRoomMapping.get(connecId); RobotUser robotUser = robotRoomMapping.get(connecId);
//更新连接的最后访问时间
EXGameController.updateLastAccessTime(connecId);
if (robotUser == null) {
System.err.println("未找到机器人用户信息连接ID: " + connecId);
return;
}
int robotId = Integer.parseInt(robotUser.getRobotId()); int robotId = Integer.parseInt(robotUser.getRobotId());
ITObject param = message.param; ITObject param = message.param;
HuNanHongZhong huNanHongZhong = getHuNanHongZhongInstance(connecId); HuNanHongZhong huNanHongZhong = getHuNanHongZhongInstance(connecId);
@ -290,6 +365,7 @@ public class RobotConnectionManager {
} }
//初始化手牌 //初始化手牌
else if ("811".equalsIgnoreCase(command)) { else if ("811".equalsIgnoreCase(command)) {
robotUser.setStatus(ROBOTEventType.ROBOT_INTOROOM_WORKING);
huNanHongZhong.cardInHead(command, message, client); huNanHongZhong.cardInHead(command, message, client);
//处理完协议后保存到Redis //处理完协议后保存到Redis
HuNanHongZhong currentInstance = huNanHongZhongInstances.get(connecId); HuNanHongZhong currentInstance = huNanHongZhongInstances.get(connecId);
@ -318,6 +394,9 @@ public class RobotConnectionManager {
if (type == 1 || type == 2) { //为1 为大结算 为2为解散,都需要恢复数据 if (type == 1 || type == 2) { //为1 为大结算 为2为解散,都需要恢复数据
//更新机器人剩余数量 //更新机器人剩余数量
updateLeftoverRobot(Integer.parseInt(robotUser.getRobotId())); updateLeftoverRobot(Integer.parseInt(robotUser.getRobotId()));
//游戏结束后主动断开连接
disconnectFromGameServer(connecId);
} }
ITObject params = TObject.newInstance(); ITObject params = TObject.newInstance();
params.putString("session", client.getSession()); params.putString("session", client.getSession());
@ -437,14 +516,15 @@ public class RobotConnectionManager {
} }
else if ("2009".equalsIgnoreCase(command)) { else if ("2009".equalsIgnoreCase(command)) {
scheduleDelay(() -> { scheduleDelay(() -> {
Jedis localJedis = Redis.use().getJedis(); Jedis jedis = null;
try { try {
jedis = Redis.use().getJedis();
Integer paramRobotId = param.getInt("aid"); Integer paramRobotId = param.getInt("aid");
if (robotUser != null) { if (robotUser != null && paramRobotId != null) {
String roomKey = String.valueOf(robotUser.getCurrentRoomId()); String roomKey = String.valueOf(robotUser.getCurrentRoomId());
//查询该房间的玩家信息 //查询该房间的玩家信息
String playersStr = jedis0.hget(roomKey, "players"); String playersStr = jedis.hget(roomKey, "players");
if (!playersStr.equals("[]")) { if (!playersStr.equals("[]")) {
String players = playersStr.substring(1, playersStr.length() - 1); String players = playersStr.substring(1, playersStr.length() - 1);
String[] playerIds = players.split(","); String[] playerIds = players.split(",");
@ -453,10 +533,6 @@ public class RobotConnectionManager {
if (playerIds.length == 1) { if (playerIds.length == 1) {
int playerId = Integer.parseInt(playerIds[0].trim()); int playerId = Integer.parseInt(playerIds[0].trim());
if (playerId == paramRobotId) { if (playerId == paramRobotId) {
String gpid = jedis0.hget(roomKey, "gpid");
String gpId = jedis0.hget(roomKey, "group");
//发送退出房间协议 //发送退出房间协议
ITObject params = TObject.newInstance(); ITObject params = TObject.newInstance();
client.send("1005", params, response -> { client.send("1005", params, response -> {
@ -471,11 +547,15 @@ public class RobotConnectionManager {
} }
} }
} }
} catch (NumberFormatException e) {
System.err.println("2009协议数字格式异常robotId: " + param.get("aid") + ", connecId: " + connecId);
} catch (NullPointerException e) {
System.err.println("2009协议空指针异常connecId: " + connecId);
} catch (Exception e) { } catch (Exception e) {
log.error("处理机器人房间映射检查时发生异常"); System.err.println("2009协议处理异常: " + e.getMessage() + ", connecId: " + connecId);
} finally { } finally {
if (localJedis != null) { if (jedis != null) {
localJedis.close(); jedis.close();
} }
} }
}, 6, TimeUnit.SECONDS); }, 6, TimeUnit.SECONDS);

View File

@ -0,0 +1,65 @@
package robot.mj.thread;
import robot.mj.EXGameController;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
/**
*
* 使
*/
public class ResourceCleanupUtil {
//需要清理的资源
private static final Set<String> pendingCleanupResources = ConcurrentHashMap.newKeySet();
/**
*
*
*/
public static void performCleanup() {
if (pendingCleanupResources.isEmpty()) {
return;
}
System.out.println("开始执行资源清理,待清理资源数: " + pendingCleanupResources.size());
int cleanedCount = 0;
Set<String> resourcesToClean = ConcurrentHashMap.newKeySet();
resourcesToClean.addAll(pendingCleanupResources);
for (String resourceId : resourcesToClean) {
try {
//从待清理列表中移除
pendingCleanupResources.remove(resourceId);
cleanedCount++;
System.out.println("已清理资源: " + resourceId);
} catch (Exception e) {
System.err.println("清理资源时发生异常: " + resourceId + ", 错误: " + e.getMessage());
}
}
System.out.println("资源清理完成,共清理: " + cleanedCount + " 个资源");
}
/**
*
*/
private static void performRegularCleanup() {
try {
//清理过期的机器人连接
EXGameController.cleanupExpiredConnections();
//输出当前系统状态
System.out.println("=== 系统资源状态 ===");
System.out.println(ThreadPoolConfig.getThreadPoolStatus());
} catch (Exception e) {
System.err.println("执行常规清理时发生异常: " + e.getMessage());
}
}
}

View File

@ -8,36 +8,36 @@ import java.util.concurrent.atomic.AtomicInteger;
*/ */
public class ThreadPoolConfig { public class ThreadPoolConfig {
// 优化后的线程池配置:针对机器人场景优化 //线程池配置
private static final ExecutorService BUSINESS_THREAD_POOL = private static final ExecutorService BUSINESS_THREAD_POOL =
new ThreadPoolExecutor( new ThreadPoolExecutor(
10, // 核心线程数 - 减少核心线程数 5, //核心线程数
50, // 最大线程数 - 降低最大线程数 20, //最大线程数
30, // 空闲线程存活时间 - 缩短存活时间 60, //空闲线程存活时间
TimeUnit.SECONDS, TimeUnit.SECONDS,
new LinkedBlockingQueue<>(10000), // 增大队列容量,减少拒绝任务 new LinkedBlockingQueue<>(5000),
new ThreadFactory() { new ThreadFactory() {
private final AtomicInteger threadNumber = new AtomicInteger(1); private final AtomicInteger threadNumber = new AtomicInteger(1);
@Override @Override
public Thread newThread(Runnable r) { public Thread newThread(Runnable r) {
Thread t = new Thread(r, "RobotBusinessThread-" + threadNumber.getAndIncrement()); Thread t = new Thread(r, "RobotBusinessThread-" + threadNumber.getAndIncrement());
t.setDaemon(true); t.setDaemon(true);
t.setPriority(Thread.NORM_PRIORITY - 2); // 进一步降低线程优先级 t.setPriority(Thread.NORM_PRIORITY - 1);
return t; return t;
} }
}, },
new ThreadPoolExecutor.CallerRunsPolicy() // 拒绝策略:由调用线程执行 new ThreadPoolExecutor.CallerRunsPolicy()
); );
// 添加定时任务线程池,专门处理延迟操作 //添加定时任务线程池
private static final ScheduledExecutorService SCHEDULED_EXECUTOR_SERVICE = private static final ScheduledExecutorService SCHEDULED_EXECUTOR_SERVICE =
Executors.newScheduledThreadPool(4, new ThreadFactory() { new ScheduledThreadPoolExecutor(2, new ThreadFactory() {
private final AtomicInteger threadNumber = new AtomicInteger(1); private final AtomicInteger threadNumber = new AtomicInteger(1);
@Override @Override
public Thread newThread(Runnable r) { public Thread newThread(Runnable r) {
Thread t = new Thread(r, "RobotScheduledThread-" + threadNumber.getAndIncrement()); Thread t = new Thread(r, "RobotScheduledThread-" + threadNumber.getAndIncrement());
t.setDaemon(true); t.setDaemon(true);
t.setPriority(Thread.NORM_PRIORITY - 2); t.setPriority(Thread.NORM_PRIORITY - 1);
return t; return t;
} }
}); });
@ -65,42 +65,49 @@ public class ThreadPoolConfig {
} }
}, delay, unit); }, 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() { public static void shutdown() {
System.out.println("开始关闭线程池..."); System.out.println("开始关闭线程池...");
// 关闭定时任务线程池 //关闭定时任务线程池
SCHEDULED_EXECUTOR_SERVICE.shutdown(); SCHEDULED_EXECUTOR_SERVICE.shutdown();
try { try {
if (!SCHEDULED_EXECUTOR_SERVICE.awaitTermination(5, TimeUnit.SECONDS)) { if (!SCHEDULED_EXECUTOR_SERVICE.awaitTermination(3, TimeUnit.SECONDS)) {
System.out.println("定时任务线程池强制关闭");
SCHEDULED_EXECUTOR_SERVICE.shutdownNow(); SCHEDULED_EXECUTOR_SERVICE.shutdownNow();
} }
} catch (InterruptedException e) { } catch (InterruptedException e) {
SCHEDULED_EXECUTOR_SERVICE.shutdownNow(); SCHEDULED_EXECUTOR_SERVICE.shutdownNow();
Thread.currentThread().interrupt(); Thread.currentThread().interrupt();
} }
// 关闭业务线程池 //关闭业务线程池
BUSINESS_THREAD_POOL.shutdown(); BUSINESS_THREAD_POOL.shutdown();
try { try {
if (!BUSINESS_THREAD_POOL.awaitTermination(10, TimeUnit.SECONDS)) { if (!BUSINESS_THREAD_POOL.awaitTermination(5, TimeUnit.SECONDS)) {
System.out.println("业务线程池强制关闭");
BUSINESS_THREAD_POOL.shutdownNow(); BUSINESS_THREAD_POOL.shutdownNow();
} }
} catch (InterruptedException e) { } catch (InterruptedException e) {
BUSINESS_THREAD_POOL.shutdownNow(); BUSINESS_THREAD_POOL.shutdownNow();
Thread.currentThread().interrupt(); Thread.currentThread().interrupt();
} }
System.out.println("线程池关闭完成"); System.out.println("线程池关闭完成");
} }
/**
* 线
*/
public static String getThreadPoolStatus() {
ThreadPoolExecutor executor = (ThreadPoolExecutor) BUSINESS_THREAD_POOL;
return String.format("线程池状态 - 核心:%d, 活跃:%d, 完成:%d, 队列:%d",
executor.getCorePoolSize(),
executor.getActiveCount(),
executor.getCompletedTaskCount(),
executor.getQueue().size());
}
} }

View File

@ -16,6 +16,7 @@ robot\mj\EXRoom.class
robot\mj\thread\ThreadPoolConfig.class robot\mj\thread\ThreadPoolConfig.class
robot\mj\thread\ThreadPoolConfig$2.class robot\mj\thread\ThreadPoolConfig$2.class
taurus\util\Util.class taurus\util\Util.class
robot\mj\thread\ResourceCleanupUtil.class
taurus\util\HongZhongSuanFaTest$HandAnalysis.class taurus\util\HongZhongSuanFaTest$HandAnalysis.class
taurus\util\HongZhongSuanFaTest.class taurus\util\HongZhongSuanFaTest.class
robot\mj\RoomCreator.class robot\mj\RoomCreator.class

View File

@ -1,15 +1,17 @@
D:\robotpro\robot_webgroup\robots\majiang\robot_mj_hz\src\main\java\robot\mj\EXPlayer.java D:\project\robot_webFenli\robots\majiang\robot_mj_hz\src\main\java\robot\mj\RoomCreator.java
D:\robotpro\robot_webgroup\robots\majiang\robot_mj_hz\src\main\java\robot\mj\handler\HuNanHongZhong.java D:\project\robot_webFenli\robots\majiang\robot_mj_hz\src\main\java\robot\mj\EXGameController.java
D:\robotpro\robot_webgroup\robots\majiang\robot_mj_hz\src\main\java\taurus\util\HongZhongSuanFaTest.java D:\project\robot_webFenli\robots\majiang\robot_mj_hz\src\main\java\robot\mj\EXPlayer.java
D:\robotpro\robot_webgroup\robots\majiang\robot_mj_hz\src\main\java\robot\mj\EXActionEvent.java D:\project\robot_webFenli\robots\majiang\robot_mj_hz\src\main\java\robot\mj\handler\HuNanHongZhong.java
D:\robotpro\robot_webgroup\robots\majiang\robot_mj_hz\src\main\java\taurus\util\ROBOTEventType.java D:\project\robot_webFenli\robots\majiang\robot_mj_hz\src\main\java\robot\mj\business\AccountBusiness.java
D:\robotpro\robot_webgroup\robots\majiang\robot_mj_hz\src\main\java\taurus\util\Util.java D:\project\robot_webFenli\robots\majiang\robot_mj_hz\src\main\java\robot\mj\EXActionEvent.java
D:\robotpro\robot_webgroup\robots\majiang\robot_mj_hz\src\main\java\robot\mj\Config.java D:\project\robot_webFenli\robots\majiang\robot_mj_hz\src\main\java\taurus\util\ROBOTEventType.java
D:\robotpro\robot_webgroup\robots\majiang\robot_mj_hz\src\main\java\robot\mj\EXMainServer.java D:\project\robot_webFenli\robots\majiang\robot_mj_hz\src\main\java\taurus\util\CardUtil.java
D:\robotpro\robot_webgroup\robots\majiang\robot_mj_hz\src\main\java\robot\mj\RobotConnectionManager.java D:\project\robot_webFenli\robots\majiang\robot_mj_hz\src\main\java\taurus\util\Util.java
D:\robotpro\robot_webgroup\robots\majiang\robot_mj_hz\src\main\java\robot\mj\info\RobotUser.java D:\project\robot_webFenli\robots\majiang\robot_mj_hz\src\main\java\robot\mj\EXMainServer.java
D:\robotpro\robot_webgroup\robots\majiang\robot_mj_hz\src\main\java\robot\mj\business\AccountBusiness.java D:\project\robot_webFenli\robots\majiang\robot_mj_hz\src\main\java\robot\mj\Config.java
D:\robotpro\robot_webgroup\robots\majiang\robot_mj_hz\src\main\java\robot\mj\EXRoom.java D:\project\robot_webFenli\robots\majiang\robot_mj_hz\src\main\java\robot\mj\thread\ResourceCleanupUtil.java
D:\robotpro\robot_webgroup\robots\majiang\robot_mj_hz\src\main\java\robot\mj\RoomCreator.java D:\project\robot_webFenli\robots\majiang\robot_mj_hz\src\main\java\taurus\util\HongZhongSuanFaTest.java
D:\robotpro\robot_webgroup\robots\majiang\robot_mj_hz\src\main\java\taurus\util\CardUtil.java D:\project\robot_webFenli\robots\majiang\robot_mj_hz\src\main\java\robot\mj\info\RobotUser.java
D:\robotpro\robot_webgroup\robots\majiang\robot_mj_hz\src\main\java\robot\mj\EXGameController.java D:\project\robot_webFenli\robots\majiang\robot_mj_hz\src\main\java\robot\mj\RobotConnectionManager.java
D:\project\robot_webFenli\robots\majiang\robot_mj_hz\src\main\java\robot\mj\thread\ThreadPoolConfig.java
D:\project\robot_webFenli\robots\majiang\robot_mj_hz\src\main\java\robot\mj\EXRoom.java

View File

@ -1 +1 @@
D:\robotpro\robot_webgroup\robots\majiang\robot_mj_hz\src\test\java\robot_mj_hongzhong\Main.java D:\project\robot_webFenli\robots\majiang\robot_mj_hz\src\test\java\robot_mj_hongzhong\Main.java