红中添加清理的资源代码
parent
f9bae0eff6
commit
0c1cee78c5
|
|
@ -12,6 +12,7 @@ import org.slf4j.Logger;
|
|||
import org.slf4j.LoggerFactory;
|
||||
import redis.clients.jedis.Jedis;
|
||||
import robot.mj.info.RobotUser;
|
||||
import robot.mj.thread.ThreadPoolConfig;
|
||||
import taurus.client.TaurusClient;
|
||||
import taurus.client.business.GroupRoomBusiness;
|
||||
import taurus.util.ROBOTEventType;
|
||||
|
|
@ -34,6 +35,12 @@ public class EXGameController extends GameController {
|
|||
//机器人房间
|
||||
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() {
|
||||
super();
|
||||
log.info("红中麻将游戏控制器已初始化");
|
||||
|
|
@ -225,31 +232,7 @@ public class EXGameController extends GameController {
|
|||
int robotId = params.getInt("robotid");
|
||||
String roomId = params.getString("roomid");
|
||||
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中该房间是否真的包含当前机器人
|
||||
if (!checkRobotInRoomRedis(roomId, String.valueOf(robotId))) {
|
||||
//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);
|
||||
//加入房间
|
||||
joinRoomCommon(params.getInt("robotid"), params.getString("roomid"), params.getInt("groupid"), params);
|
||||
|
|
@ -390,7 +386,7 @@ public class EXGameController extends GameController {
|
|||
} catch (InterruptedException e) {
|
||||
log.error("加入房间超时异常");
|
||||
}
|
||||
});
|
||||
}, ThreadPoolConfig.getBusinessThreadPool());//指定自定义线程池
|
||||
robotUser.setIntoRoomTime(robotConnectionManager.getTime());
|
||||
System.err.println("已进入房间准备成功: " + robotUser.getConnecId());
|
||||
} catch (Exception e) {
|
||||
|
|
@ -438,7 +434,51 @@ public class EXGameController extends GameController {
|
|||
* 根据机器人ID删除其所在的房间信息
|
||||
*/
|
||||
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() + " 个超时连接");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -11,6 +11,8 @@ import org.slf4j.Logger;
|
|||
import org.slf4j.LoggerFactory;
|
||||
import redis.clients.jedis.Jedis;
|
||||
import robot.mj.info.RobotUser;
|
||||
import robot.mj.thread.ResourceCleanupUtil;
|
||||
import robot.mj.thread.ThreadPoolConfig;
|
||||
import taurus.client.NetManager;
|
||||
|
||||
import static robot.mj.EXGameController.robotRoomMapping;
|
||||
|
|
@ -28,10 +30,34 @@ public class EXMainServer extends MainServer{
|
|||
public void 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. 先启动独立的事件处理线程(只启动一次)
|
||||
startNetEventThread();
|
||||
|
||||
// 2. 启动连接检查定时任务
|
||||
// 2. 启动资源清理定时任务
|
||||
startResourceCleanupScheduler();
|
||||
|
||||
// 3. 启动连接检查定时任务
|
||||
//startConnectionCheckScheduler();
|
||||
//测试
|
||||
Jedis jedis2 = Redis.use("group1_db2").getJedis();
|
||||
|
|
@ -63,6 +89,7 @@ public class EXMainServer extends MainServer{
|
|||
//5、干活
|
||||
log.info("红中麻将机器人服务器已启动");
|
||||
log.info("服务器将监听端口 {} 用于接收robot_mgr管理协议", gameSetting.port);
|
||||
System.out.println("当前线程池配置: " + ThreadPoolConfig.getThreadPoolStatus());
|
||||
|
||||
jedis2.close();
|
||||
}
|
||||
|
|
@ -87,7 +114,35 @@ public class EXMainServer extends MainServer{
|
|||
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
|
||||
public Room newRoom(String roomid, Map<String, String> redis_room_map) {
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ import taurus.client.MessageResponse;
|
|||
import taurus.client.TaurusClient;
|
||||
import taurus.client.SocketCode;
|
||||
import redis.clients.jedis.Jedis;
|
||||
import taurus.util.ROBOTEventType;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.*;
|
||||
|
|
@ -32,6 +33,15 @@ public class RobotConnectionManager {
|
|||
|
||||
private static final Map<String, HuNanHongZhong> huNanHongZhongInstances = new ConcurrentHashMap<>();
|
||||
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 String host= Config.GAME_SERVER_HOST;
|
||||
|
|
@ -46,6 +56,13 @@ public class RobotConnectionManager {
|
|||
* 获取红中麻将处理器实例
|
||||
*/
|
||||
private HuNanHongZhong getHuNanHongZhongInstance(String connecId) {
|
||||
//标记连接为活跃状态
|
||||
activeConnections.add(connecId);
|
||||
connectionCreationTime.put(connecId, System.currentTimeMillis());
|
||||
|
||||
//定期清理过期连接
|
||||
cleanupExpiredInstances();
|
||||
|
||||
HuNanHongZhong existingInstance = huNanHongZhongInstances.get(connecId);
|
||||
if (existingInstance != null) {
|
||||
return existingInstance;
|
||||
|
|
@ -101,6 +118,10 @@ public class RobotConnectionManager {
|
|||
System.out.println("开始主动断开连接: {"+connecId+"}");
|
||||
RobotUser robotUser = robotRoomMapping.remove(connecId);
|
||||
|
||||
//标记连接为非活跃
|
||||
activeConnections.remove(connecId);
|
||||
connectionCreationTime.remove(connecId);
|
||||
|
||||
//清理连接数据
|
||||
if (connecId != null) {
|
||||
HuNanHongZhong.removeFromRedis(connecId);
|
||||
|
|
@ -129,6 +150,34 @@ public class RobotConnectionManager {
|
|||
} else {
|
||||
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);
|
||||
currentInstance.outCard(client);
|
||||
/*sleepTime(2000);
|
||||
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 {
|
||||
System.err.println("警告:重连时未获取到手牌数据");
|
||||
}
|
||||
|
|
@ -274,6 +340,15 @@ public class RobotConnectionManager {
|
|||
*/
|
||||
private void handleProtocol(String command, Message message, TaurusClient client, String connecId) {
|
||||
RobotUser robotUser = robotRoomMapping.get(connecId);
|
||||
|
||||
//更新连接的最后访问时间
|
||||
EXGameController.updateLastAccessTime(connecId);
|
||||
|
||||
if (robotUser == null) {
|
||||
System.err.println("未找到机器人用户信息,连接ID: " + connecId);
|
||||
return;
|
||||
}
|
||||
|
||||
int robotId = Integer.parseInt(robotUser.getRobotId());
|
||||
ITObject param = message.param;
|
||||
HuNanHongZhong huNanHongZhong = getHuNanHongZhongInstance(connecId);
|
||||
|
|
@ -290,6 +365,7 @@ public class RobotConnectionManager {
|
|||
}
|
||||
//初始化手牌
|
||||
else if ("811".equalsIgnoreCase(command)) {
|
||||
robotUser.setStatus(ROBOTEventType.ROBOT_INTOROOM_WORKING);
|
||||
huNanHongZhong.cardInHead(command, message, client);
|
||||
//处理完协议后保存到Redis
|
||||
HuNanHongZhong currentInstance = huNanHongZhongInstances.get(connecId);
|
||||
|
|
@ -318,6 +394,9 @@ public class RobotConnectionManager {
|
|||
if (type == 1 || type == 2) { //为1 为大结算 为2为解散,都需要恢复数据
|
||||
//更新机器人剩余数量
|
||||
updateLeftoverRobot(Integer.parseInt(robotUser.getRobotId()));
|
||||
|
||||
//游戏结束后主动断开连接
|
||||
disconnectFromGameServer(connecId);
|
||||
}
|
||||
ITObject params = TObject.newInstance();
|
||||
params.putString("session", client.getSession());
|
||||
|
|
@ -437,14 +516,15 @@ public class RobotConnectionManager {
|
|||
}
|
||||
else if ("2009".equalsIgnoreCase(command)) {
|
||||
scheduleDelay(() -> {
|
||||
Jedis localJedis = Redis.use().getJedis();
|
||||
Jedis jedis = null;
|
||||
try {
|
||||
jedis = Redis.use().getJedis();
|
||||
Integer paramRobotId = param.getInt("aid");
|
||||
if (robotUser != null) {
|
||||
if (robotUser != null && paramRobotId != null) {
|
||||
String roomKey = String.valueOf(robotUser.getCurrentRoomId());
|
||||
|
||||
//查询该房间的玩家信息
|
||||
String playersStr = jedis0.hget(roomKey, "players");
|
||||
String playersStr = jedis.hget(roomKey, "players");
|
||||
if (!playersStr.equals("[]")) {
|
||||
String players = playersStr.substring(1, playersStr.length() - 1);
|
||||
String[] playerIds = players.split(",");
|
||||
|
|
@ -453,10 +533,6 @@ public class RobotConnectionManager {
|
|||
if (playerIds.length == 1) {
|
||||
int playerId = Integer.parseInt(playerIds[0].trim());
|
||||
if (playerId == paramRobotId) {
|
||||
|
||||
String gpid = jedis0.hget(roomKey, "gpid");
|
||||
String gpId = jedis0.hget(roomKey, "group");
|
||||
|
||||
//发送退出房间协议
|
||||
ITObject params = TObject.newInstance();
|
||||
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) {
|
||||
log.error("处理机器人房间映射检查时发生异常");
|
||||
System.err.println("2009协议处理异常: " + e.getMessage() + ", connecId: " + connecId);
|
||||
} finally {
|
||||
if (localJedis != null) {
|
||||
localJedis.close();
|
||||
if (jedis != null) {
|
||||
jedis.close();
|
||||
}
|
||||
}
|
||||
}, 6, TimeUnit.SECONDS);
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -8,36 +8,36 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||
*/
|
||||
public class ThreadPoolConfig {
|
||||
|
||||
// 优化后的线程池配置:针对机器人场景优化
|
||||
//线程池配置
|
||||
private static final ExecutorService BUSINESS_THREAD_POOL =
|
||||
new ThreadPoolExecutor(
|
||||
10, // 核心线程数 - 减少核心线程数
|
||||
50, // 最大线程数 - 降低最大线程数
|
||||
30, // 空闲线程存活时间 - 缩短存活时间
|
||||
5, //核心线程数
|
||||
20, //最大线程数
|
||||
60, //空闲线程存活时间
|
||||
TimeUnit.SECONDS,
|
||||
new LinkedBlockingQueue<>(10000), // 增大队列容量,减少拒绝任务
|
||||
new LinkedBlockingQueue<>(5000),
|
||||
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); // 进一步降低线程优先级
|
||||
t.setPriority(Thread.NORM_PRIORITY - 1);
|
||||
return t;
|
||||
}
|
||||
},
|
||||
new ThreadPoolExecutor.CallerRunsPolicy() // 拒绝策略:由调用线程执行
|
||||
new ThreadPoolExecutor.CallerRunsPolicy()
|
||||
);
|
||||
|
||||
// 添加定时任务线程池,专门处理延迟操作
|
||||
|
||||
//添加定时任务线程池
|
||||
private static final ScheduledExecutorService SCHEDULED_EXECUTOR_SERVICE =
|
||||
Executors.newScheduledThreadPool(4, new ThreadFactory() {
|
||||
new ScheduledThreadPoolExecutor(2, 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);
|
||||
t.setPriority(Thread.NORM_PRIORITY - 1);
|
||||
return t;
|
||||
}
|
||||
});
|
||||
|
|
@ -65,42 +65,49 @@ public class ThreadPoolConfig {
|
|||
}
|
||||
}, 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)) {
|
||||
if (!SCHEDULED_EXECUTOR_SERVICE.awaitTermination(3, TimeUnit.SECONDS)) {
|
||||
System.out.println("定时任务线程池强制关闭");
|
||||
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)) {
|
||||
if (!BUSINESS_THREAD_POOL.awaitTermination(5, TimeUnit.SECONDS)) {
|
||||
System.out.println("业务线程池强制关闭");
|
||||
BUSINESS_THREAD_POOL.shutdownNow();
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
BUSINESS_THREAD_POOL.shutdownNow();
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
|
||||
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -16,6 +16,7 @@ robot\mj\EXRoom.class
|
|||
robot\mj\thread\ThreadPoolConfig.class
|
||||
robot\mj\thread\ThreadPoolConfig$2.class
|
||||
taurus\util\Util.class
|
||||
robot\mj\thread\ResourceCleanupUtil.class
|
||||
taurus\util\HongZhongSuanFaTest$HandAnalysis.class
|
||||
taurus\util\HongZhongSuanFaTest.class
|
||||
robot\mj\RoomCreator.class
|
||||
|
|
|
|||
|
|
@ -1,15 +1,17 @@
|
|||
D:\robotpro\robot_webgroup\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\handler\HuNanHongZhong.java
|
||||
D:\robotpro\robot_webgroup\robots\majiang\robot_mj_hz\src\main\java\taurus\util\HongZhongSuanFaTest.java
|
||||
D:\robotpro\robot_webgroup\robots\majiang\robot_mj_hz\src\main\java\robot\mj\EXActionEvent.java
|
||||
D:\robotpro\robot_webgroup\robots\majiang\robot_mj_hz\src\main\java\taurus\util\ROBOTEventType.java
|
||||
D:\robotpro\robot_webgroup\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\Config.java
|
||||
D:\robotpro\robot_webgroup\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\RobotConnectionManager.java
|
||||
D:\robotpro\robot_webgroup\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\business\AccountBusiness.java
|
||||
D:\robotpro\robot_webgroup\robots\majiang\robot_mj_hz\src\main\java\robot\mj\EXRoom.java
|
||||
D:\robotpro\robot_webgroup\robots\majiang\robot_mj_hz\src\main\java\robot\mj\RoomCreator.java
|
||||
D:\robotpro\robot_webgroup\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\EXGameController.java
|
||||
D:\project\robot_webFenli\robots\majiang\robot_mj_hz\src\main\java\robot\mj\RoomCreator.java
|
||||
D:\project\robot_webFenli\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\EXPlayer.java
|
||||
D:\project\robot_webFenli\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\business\AccountBusiness.java
|
||||
D:\project\robot_webFenli\robots\majiang\robot_mj_hz\src\main\java\robot\mj\EXActionEvent.java
|
||||
D:\project\robot_webFenli\robots\majiang\robot_mj_hz\src\main\java\taurus\util\ROBOTEventType.java
|
||||
D:\project\robot_webFenli\robots\majiang\robot_mj_hz\src\main\java\taurus\util\CardUtil.java
|
||||
D:\project\robot_webFenli\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\EXMainServer.java
|
||||
D:\project\robot_webFenli\robots\majiang\robot_mj_hz\src\main\java\robot\mj\Config.java
|
||||
D:\project\robot_webFenli\robots\majiang\robot_mj_hz\src\main\java\robot\mj\thread\ResourceCleanupUtil.java
|
||||
D:\project\robot_webFenli\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\info\RobotUser.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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Binary file not shown.
Loading…
Reference in New Issue