辅助控制线程使用优化
This commit is contained in:
parent
1248e5543b
commit
9ba1be252f
@ -17,7 +17,7 @@ package com.yfd.platform.component.iec104.client;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.yfd.platform.component.iec104.config.Iec104Config;
|
||||
import com.yfd.platform.component.iec104.core.CachedThreadPool;
|
||||
import com.yfd.platform.component.iec104.core.OptimizedThreadPool;
|
||||
import com.yfd.platform.component.iec104.server.Iec104Master;
|
||||
import com.yfd.platform.component.iec104.server.Iec104MasterFactory;
|
||||
import com.yfd.platform.modules.auxcontrol.domain.GatewayDevice;
|
||||
@ -70,7 +70,8 @@ public class IEC104ClientRunner implements ApplicationRunner {
|
||||
iec104Config.setTerminnalAddress(terminnalAddress);
|
||||
iec104Config.setSlaveCode(gatewayDevice.getDeviceCode());
|
||||
iec104Config.setSlaveIP(gatewayDevice.getIpAddr());
|
||||
Runnable runnable = () -> {
|
||||
OptimizedThreadPool threadPool = OptimizedThreadPool.getInstance();
|
||||
threadPool.execute(() -> {
|
||||
Iec104Master iec104server = Iec104MasterFactory.createTcpClientMaster(iec104Config.getSlaveIP(),
|
||||
2404);
|
||||
try {
|
||||
@ -79,8 +80,8 @@ public class IEC104ClientRunner implements ApplicationRunner {
|
||||
} catch (Exception e) {
|
||||
log.error(String.format("%s-对应的终端连接失败!", iec104Config.getSlaveIP()));
|
||||
}
|
||||
};
|
||||
CachedThreadPool.getCachedThreadPool().execute(runnable);
|
||||
});
|
||||
threadPool.shutdown();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,26 +0,0 @@
|
||||
package com.yfd.platform.component.iec104.core;
|
||||
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
/**
|
||||
* 线程池
|
||||
*/
|
||||
public final class CachedThreadPool {
|
||||
|
||||
private static CachedThreadPool cachedThreadPool = new CachedThreadPool();
|
||||
private ExecutorService executorService;
|
||||
|
||||
private CachedThreadPool() {
|
||||
executorService = Executors.newCachedThreadPool();
|
||||
}
|
||||
|
||||
public static CachedThreadPool getCachedThreadPool() {
|
||||
return cachedThreadPool;
|
||||
}
|
||||
|
||||
public void execute(Runnable runnable) {
|
||||
executorService.execute(runnable);
|
||||
}
|
||||
|
||||
}
|
@ -1,8 +1,11 @@
|
||||
package com.yfd.platform.component.iec104.core;
|
||||
|
||||
import com.yfd.platform.component.iec104.client.MasterSysDataHandler;
|
||||
import com.yfd.platform.component.iec104.common.Iec104Constant;
|
||||
import com.yfd.platform.component.iec104.message.MessageDetail;
|
||||
import com.ydl.iec.util.Iec104Util;
|
||||
import com.yfd.platform.component.iec104.server.Iec104Master;
|
||||
import com.yfd.platform.component.iec104.server.Iec104MasterFactory;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@ -59,7 +62,8 @@ public class ControlManageUtil {
|
||||
* 启动S发送S确认帧 的任务
|
||||
*/
|
||||
public void startSendFrameTask() {
|
||||
Runnable runnable = () -> {
|
||||
OptimizedThreadPool threadPool = OptimizedThreadPool.getInstance();
|
||||
threadPool.execute(() -> {
|
||||
while (true) {
|
||||
try {
|
||||
synchronized (sendSframeLock) {
|
||||
@ -76,8 +80,9 @@ public class ControlManageUtil {
|
||||
LOGGER.error("Exception caught", e);
|
||||
}
|
||||
}
|
||||
};
|
||||
CachedThreadPool.getCachedThreadPool().execute(runnable);
|
||||
});
|
||||
threadPool.shutdown();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -0,0 +1,125 @@
|
||||
package com.yfd.platform.component.iec104.core;
|
||||
|
||||
import java.util.concurrent.*;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/**
|
||||
* 优化后的线程池管理类
|
||||
* 说明:使用可控的自定义线程池替代无界的CachedThreadPool
|
||||
*/
|
||||
public final class OptimizedThreadPool {
|
||||
|
||||
// 使用静态内部类实现线程安全的单例模式
|
||||
private static class InstanceHolder {
|
||||
|
||||
private static final OptimizedThreadPool INSTANCE = new OptimizedThreadPool();
|
||||
}
|
||||
|
||||
private final ThreadPoolExecutor executorService;
|
||||
|
||||
// 私有构造函数防止外部实例化
|
||||
private OptimizedThreadPool() {
|
||||
// 获取处理器核心数(动态适配不同机器)
|
||||
int corePoolSize = Runtime.getRuntime().availableProcessors();
|
||||
|
||||
// 配置线程池参数(生产环境建议参数可配置化)
|
||||
this.executorService = new ThreadPoolExecutor(
|
||||
// 核心线程数(建议等于CPU核心数)
|
||||
corePoolSize,
|
||||
// 最大线程数(建议2-4倍核心数)
|
||||
corePoolSize * 2,
|
||||
// 空闲线程存活时间(秒)
|
||||
60L,
|
||||
// 时间单位
|
||||
TimeUnit.SECONDS,
|
||||
// 有界任务队列(防止OOM)
|
||||
new LinkedBlockingQueue<>(1000),
|
||||
// 自定义线程工厂(便于问题排查)
|
||||
new CustomThreadFactory(),
|
||||
// 拒绝策略(主线程执行)
|
||||
new ThreadPoolExecutor.CallerRunsPolicy()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取线程池单例实例(线程安全)
|
||||
*/
|
||||
public static OptimizedThreadPool getInstance() {
|
||||
return InstanceHolder.INSTANCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行异步任务(增强版)
|
||||
*/
|
||||
public void execute(Runnable task) {
|
||||
// 添加基础校验(生产环境可扩展)
|
||||
if (task == null) {
|
||||
throw new IllegalArgumentException("Task cannot be null");
|
||||
}
|
||||
|
||||
// 添加异常处理包装
|
||||
executorService.execute(wrapTask(task));
|
||||
}
|
||||
|
||||
/**
|
||||
* 任务包装器(统一异常处理)
|
||||
*/
|
||||
private Runnable wrapTask(Runnable task) {
|
||||
return () -> {
|
||||
try {
|
||||
task.run();
|
||||
} catch (Exception e) {
|
||||
// 统一的异常处理(建议接入日志系统)
|
||||
System.err.println("Task execution failed: " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 优雅关闭线程池(重要!必须调用)
|
||||
*/
|
||||
public void shutdown() {
|
||||
executorService.shutdown();
|
||||
try {
|
||||
// 等待任务完成(可配置超时时间)
|
||||
if (!executorService.awaitTermination(60, TimeUnit.SECONDS)) {
|
||||
executorService.shutdownNow();
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
executorService.shutdownNow();
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取线程池状态(监控用)
|
||||
*/
|
||||
public String getPoolStatus() {
|
||||
return String.format(
|
||||
"Pool Status: [Active: %d, Core: %d, Max: %d, Queue: %d/%d]",
|
||||
executorService.getActiveCount(),
|
||||
executorService.getCorePoolSize(),
|
||||
executorService.getMaximumPoolSize(),
|
||||
executorService.getQueue().size(),
|
||||
executorService.getQueue().remainingCapacity()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 自定义线程工厂(命名规范化)
|
||||
*/
|
||||
private static class CustomThreadFactory implements ThreadFactory {
|
||||
|
||||
private final AtomicInteger threadCounter = new AtomicInteger(1);
|
||||
private static final String THREAD_NAME_PREFIX = "optimized-pool-thread-";
|
||||
|
||||
@Override
|
||||
public Thread newThread(Runnable r) {
|
||||
Thread thread = new Thread(r, THREAD_NAME_PREFIX + threadCounter.getAndIncrement());
|
||||
thread.setDaemon(false); // 非守护线程
|
||||
thread.setPriority(Thread.NORM_PRIORITY);
|
||||
return thread;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,8 +1,11 @@
|
||||
package com.yfd.platform.component.iec104.core;
|
||||
|
||||
import cn.hutool.core.util.ObjUtil;
|
||||
import com.yfd.platform.component.iec104.client.MasterSysDataHandler;
|
||||
import com.yfd.platform.component.iec104.common.BasicInstruction104;
|
||||
import com.yfd.platform.component.iec104.message.MessageDetail;
|
||||
import com.yfd.platform.component.iec104.server.Iec104Master;
|
||||
import com.yfd.platform.component.iec104.server.Iec104MasterFactory;
|
||||
import com.yfd.platform.component.iec104.server.master.BootNettyClientChannel;
|
||||
import com.yfd.platform.component.iec104.server.master.BootNettyClientChannelCache;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
@ -71,12 +74,13 @@ public class ScheduledTaskPool {
|
||||
* @Description: 发送测试帧
|
||||
*/
|
||||
private void sendTestFrame() {
|
||||
Runnable runnable = () -> {
|
||||
OptimizedThreadPool threadPool = OptimizedThreadPool.getInstance();
|
||||
threadPool.execute(() -> {
|
||||
try {
|
||||
BootNettyClientChannel Channel= BootNettyClientChannelCache.get(ctx.channel().id().asShortText());
|
||||
if(ObjUtil.isNotEmpty(Channel)){
|
||||
String slave_ip= Channel.getCode();
|
||||
LOGGER.info(String.format("向从站[%s]发送测试链路指令!",slave_ip));
|
||||
BootNettyClientChannel channel = BootNettyClientChannelCache.get(ctx.channel().id().asShortText());
|
||||
if(ObjUtil.isNotEmpty(channel )){
|
||||
String slaveIp = channel .getCode();
|
||||
LOGGER.info(String.format("向从站[%s]发送测试链路指令!",slaveIp ));
|
||||
ctx.channel().writeAndFlush(BasicInstruction104.TESTFR);
|
||||
//对时指令
|
||||
ctx.channel().writeAndFlush(BasicInstruction104.getTimeScale104());
|
||||
@ -84,8 +88,8 @@ public class ScheduledTaskPool {
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("Exception caught", e);
|
||||
}
|
||||
};
|
||||
CachedThreadPool.getCachedThreadPool().execute(runnable);
|
||||
});
|
||||
threadPool.shutdown();
|
||||
}
|
||||
|
||||
|
||||
@ -99,7 +103,8 @@ public class ScheduledTaskPool {
|
||||
}
|
||||
|
||||
private void sendGeneralCall() {
|
||||
Runnable runnable = () -> {
|
||||
OptimizedThreadPool threadPool = OptimizedThreadPool.getInstance();
|
||||
threadPool.execute(() -> {
|
||||
try {
|
||||
BootNettyClientChannel channel = BootNettyClientChannelCache.get(ctx.channel().id().asShortText());
|
||||
if (ObjUtil.isNotEmpty(channel)) {
|
||||
@ -111,8 +116,8 @@ public class ScheduledTaskPool {
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("Exception caught", e);
|
||||
}
|
||||
};
|
||||
CachedThreadPool.getCachedThreadPool().execute(runnable);
|
||||
});
|
||||
threadPool.shutdown();
|
||||
}
|
||||
|
||||
public void stopSendCommandTask() {
|
||||
|
@ -1,10 +1,8 @@
|
||||
package com.yfd.platform.component.iec104.server.master.handler;
|
||||
|
||||
import cn.hutool.core.util.ObjUtil;
|
||||
import com.yfd.platform.component.iec104.core.CachedThreadPool;
|
||||
import com.yfd.platform.component.iec104.core.ControlManageUtil;
|
||||
import com.yfd.platform.component.iec104.core.Iec104ThreadLocal;
|
||||
import com.yfd.platform.component.iec104.core.ScheduledTaskPool;
|
||||
import com.yfd.platform.component.iec104.common.BasicInstruction104;
|
||||
import com.yfd.platform.component.iec104.core.*;
|
||||
import com.yfd.platform.component.iec104.message.MessageDetail;
|
||||
import com.yfd.platform.component.iec104.server.handler.ChannelHandlerImpl;
|
||||
import com.yfd.platform.component.iec104.server.handler.DataHandler;
|
||||
@ -52,16 +50,15 @@ public class Iec104ClientHandler extends SimpleChannelInboundHandler<MessageDeta
|
||||
BootNettyClientChannelCache.save(ctx.channel().id().asShortText(),Channel);
|
||||
|
||||
if (dataHandler != null) {
|
||||
CachedThreadPool.getCachedThreadPool().execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
dataHandler.handlerAdded(new ChannelHandlerImpl(ctx));
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("Exception caught", e);
|
||||
}
|
||||
OptimizedThreadPool threadPool = OptimizedThreadPool.getInstance();
|
||||
threadPool.execute(() -> {
|
||||
try {
|
||||
dataHandler.handlerAdded(new ChannelHandlerImpl(ctx));
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("Exception caught", e);
|
||||
}
|
||||
});
|
||||
threadPool.shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
@ -80,17 +77,16 @@ public class Iec104ClientHandler extends SimpleChannelInboundHandler<MessageDeta
|
||||
@Override
|
||||
public void channelRead0(ChannelHandlerContext ctx, MessageDetail ruleDetail104) throws IOException {
|
||||
if (dataHandler != null) {
|
||||
CachedThreadPool.getCachedThreadPool().execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
dataHandler.channelRead(new ChannelHandlerImpl(ctx), ruleDetail104);
|
||||
} catch (Exception e) {
|
||||
// TODO Auto-generated catch block
|
||||
LOGGER.error("Exception caught", e);
|
||||
}
|
||||
}
|
||||
});
|
||||
OptimizedThreadPool threadPool = OptimizedThreadPool.getInstance();
|
||||
threadPool.execute(() -> {
|
||||
try {
|
||||
dataHandler.channelRead(new ChannelHandlerImpl(ctx), ruleDetail104);
|
||||
} catch (Exception e) {
|
||||
// TODO Auto-generated catch block
|
||||
LOGGER.error("Exception caught", e);
|
||||
}
|
||||
});
|
||||
threadPool.shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,18 +1,17 @@
|
||||
package com.yfd.platform.component.iec104.server.slave.handler;
|
||||
|
||||
|
||||
import com.yfd.platform.component.iec104.core.CachedThreadPool;
|
||||
import com.yfd.platform.component.iec104.core.ControlManageUtil;
|
||||
import com.yfd.platform.component.iec104.core.Iec104ThreadLocal;
|
||||
import com.yfd.platform.component.iec104.core.OptimizedThreadPool;
|
||||
import com.yfd.platform.component.iec104.message.MessageDetail;
|
||||
import com.yfd.platform.component.iec104.server.handler.ChannelHandlerImpl;
|
||||
import com.yfd.platform.component.iec104.server.handler.DataHandler;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.ChannelInboundHandlerAdapter;
|
||||
import io.netty.channel.SimpleChannelInboundHandler;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import io.netty.channel.ChannelInboundHandlerAdapter;
|
||||
|
||||
/**
|
||||
*
|
||||
@ -42,15 +41,15 @@ public class Iec104TcpSlaveHandler extends SimpleChannelInboundHandler<MessageDe
|
||||
*/
|
||||
Iec104ThreadLocal.getControlPool().startSendFrameTask();
|
||||
if (dataHandler != null) {
|
||||
Runnable runnable = () -> {
|
||||
OptimizedThreadPool threadPool = OptimizedThreadPool.getInstance();
|
||||
threadPool.execute(() -> {
|
||||
try {
|
||||
dataHandler.handlerAdded(new ChannelHandlerImpl(ctx));
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("Exception caught", e);
|
||||
}
|
||||
};
|
||||
|
||||
CachedThreadPool.getCachedThreadPool().execute(runnable);
|
||||
});
|
||||
threadPool.shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
@ -67,15 +66,17 @@ public class Iec104TcpSlaveHandler extends SimpleChannelInboundHandler<MessageDe
|
||||
@Override
|
||||
protected void channelRead0(ChannelHandlerContext ctx, MessageDetail ruleDetail104) throws Exception {
|
||||
if (dataHandler != null) {
|
||||
Runnable runnable = () -> {
|
||||
|
||||
OptimizedThreadPool threadPool = OptimizedThreadPool.getInstance();
|
||||
threadPool.execute(() -> {
|
||||
try {
|
||||
dataHandler.channelRead(new ChannelHandlerImpl(ctx), ruleDetail104);
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("Exception caught", e);
|
||||
}
|
||||
};
|
||||
CachedThreadPool.getCachedThreadPool().execute(runnable);
|
||||
}
|
||||
});
|
||||
threadPool.shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,32 +0,0 @@
|
||||
package com.yfd.platform.uavsystem.conf.thread;
|
||||
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
|
||||
public class MyThread {
|
||||
|
||||
|
||||
|
||||
public static ThreadPoolExecutor getThread(String threadName){
|
||||
ThreadPoolExecutor threadPoolExecutor= new ThreadPoolExecutor(3,12,60, TimeUnit.SECONDS,new LinkedBlockingQueue<>(1000),new MyThreadFactory(threadName), new MyAbortPolicy());
|
||||
return threadPoolExecutor;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param threadNum 核心线程数
|
||||
* @param threadMaxNum 最大线程数
|
||||
* @param timeOut 超时时间,单位秒
|
||||
* @param QueueNum 队列数量
|
||||
* @param threadName 线程名称(前缀)
|
||||
* @return ThreadPoolExecutor
|
||||
*/
|
||||
|
||||
public static ThreadPoolExecutor getThread(Integer threadNum,Integer threadMaxNum,Long timeOut,Integer QueueNum,String threadName){
|
||||
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(threadNum,threadMaxNum,timeOut, TimeUnit.SECONDS,new LinkedBlockingQueue<>(QueueNum),new MyThreadFactory(threadName), new MyAbortPolicy());
|
||||
return threadPoolExecutor;
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user