package chuankou;
|
import java.text.SimpleDateFormat;
|
import java.util.Date;
|
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
import javax.swing.SwingWorker;
|
|
|
/**
|
* 串口消息发送工具类
|
* 提供高性能的串口消息发送功能,适合高频调用
|
* 优化内存使用,避免长时间运行内存泄漏
|
*/
|
public class Sendmsg {
|
// 静态串口服务实例
|
private static volatile SerialPortService serialService = null;
|
private static final AtomicBoolean isPortOpen = new AtomicBoolean(false);
|
|
// 改为非final,支持动态控制
|
private static volatile boolean DEBUG_MODE = false;
|
|
// 使用ThreadLocal保证SimpleDateFormat线程安全
|
private static final ThreadLocal<SimpleDateFormat> TIME_FORMATTER =
|
ThreadLocal.withInitial(() -> new SimpleDateFormat("HH:mm:ss.SSS"));
|
|
// 缓存字符串构建器,减少对象创建
|
private static final ThreadLocal<StringBuilder> STRING_BUILDER_CACHE =
|
ThreadLocal.withInitial(() -> new StringBuilder(128));
|
|
// 记录活跃的SwingWorker,便于管理
|
private static final ConcurrentHashMap<String, SwingWorker<?, ?>> ACTIVE_WORKERS =
|
new ConcurrentHashMap<>();
|
|
|
|
|
/**
|
* HEX字符串转字节数组
|
* @param s HEX字符串
|
* @return 字节数组
|
*/
|
private static byte[] hexStringToByteArray(String s) {
|
if (s == null || s.isEmpty()) {
|
return new byte[0];
|
}
|
|
s = s.replaceAll("\\s+", ""); // 移除空格
|
int len = s.length();
|
if (len % 2 != 0) {
|
throw new IllegalArgumentException("HEX字符串长度必须为偶数,当前长度: " + len + ", 数据: " + s);
|
}
|
|
byte[] data = new byte[len / 2];
|
for (int i = 0; i < len; i += 2) {
|
int high = Character.digit(s.charAt(i), 16);
|
int low = Character.digit(s.charAt(i + 1), 16);
|
|
if (high == -1 || low == -1) {
|
throw new IllegalArgumentException("无效的HEX字符: '" + s.charAt(i) + s.charAt(i + 1) + "' 在位置 " + i + "-" + (i+1) + ", 完整数据: " + s);
|
}
|
|
data[i / 2] = (byte) ((high << 4) + low);
|
}
|
return data;
|
}
|
|
/**
|
* 字节数组转HEX字符串
|
* @param bytes 字节数组
|
* @return HEX字符串
|
*/
|
public static String bytesToHex(byte[] bytes) {
|
if (bytes == null || bytes.length == 0) {
|
return "";
|
}
|
|
StringBuilder sb = STRING_BUILDER_CACHE.get();
|
sb.setLength(0);
|
for (byte b : bytes) {
|
sb.append(String.format("%02x", b));
|
}
|
return sb.toString();
|
}
|
|
/**
|
* 获取当前时间字符串
|
* @return 时间字符串
|
*/
|
private static String getCurrentTime() {
|
return TIME_FORMATTER.get().format(new Date());
|
}
|
|
/**
|
* 启用调试模式
|
*/
|
public static void enableDebugMode() {
|
DEBUG_MODE = true;
|
System.out.println("[" + getCurrentTime() + "] Sendmsg调试模式已启用");
|
}
|
|
/**
|
* 禁用调试模式
|
*/
|
public static void disableDebugMode() {
|
DEBUG_MODE = false;
|
System.out.println("[" + getCurrentTime() + "] Sendmsg调试模式已禁用");
|
}
|
|
/**
|
* 设置调试模式
|
*/
|
public static void setDebugMode(boolean debug) {
|
DEBUG_MODE = debug;
|
System.out.println("[" + getCurrentTime() + "] Sendmsg调试模式: " + (debug ? "启用" : "禁用"));
|
}
|
|
/**
|
* 清理资源,防止内存泄漏
|
*/
|
public static void cleanup() {
|
|
|
// 清理ThreadLocal资源
|
TIME_FORMATTER.remove();
|
STRING_BUILDER_CACHE.remove();
|
|
if (DEBUG_MODE) {
|
System.out.println("[" + getCurrentTime() + "] Sendmsg资源清理完成");
|
}
|
}
|
|
/**
|
* 获取活跃任务数量
|
*/
|
public static int getActiveTaskCount() {
|
return ACTIVE_WORKERS.size();
|
}
|
}
|