package chushihua;
|
|
import xitongshezhi.Fkj;
|
import xitongshezhi.SystemDebugDialog;
|
|
import java.util.ArrayList;
|
import java.util.List;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
|
/**
|
* 在线轮询类 - 优化版本
|
* 专门用于定时轮询有卡的卡槽并发送查询指令
|
* 与原有的轮询查询类互补,专注于在线设备的持续监控
|
*/
|
public class lunxunzaixian {
|
private static final AtomicBoolean isRunning = new AtomicBoolean(false);
|
private static final AtomicBoolean isPaused = new AtomicBoolean(false);
|
private static final AtomicBoolean shouldStop = new AtomicBoolean(false);
|
private static Thread onlinePollingThread;
|
|
// 可配置的轮询参数(不再是final)
|
private static int cycleInterval = 60000; // 完整轮询周期间隔:60秒
|
private static int slotInterval = 200; // 卡槽间查询间隔:200毫秒
|
|
// 卡槽相关常量
|
private static final int MIN_SLOT = 1;
|
private static final int MAX_SLOT = 60;
|
|
// 性能优化配置
|
private static final int BATCH_SIZE = 5; // 批量查询大小
|
private static int consecutiveFailures = 0;
|
private static final int MAX_CONSECUTIVE_FAILURES = 3;
|
|
/**
|
* 启动在线轮询 - 优化版本
|
* @return true-启动成功, false-启动失败
|
*/
|
public static boolean startOnlinePolling() {
|
if (isRunning.get()) {
|
SystemDebugDialog.appendAsciiData("Online polling is already in progress");
|
return true;
|
}
|
|
// 检查串口连接状态
|
if (!checkSerialConnectionWithRetry()) {
|
System.err.println("串口未连接,无法启动在线轮询");
|
return false;
|
}
|
|
isRunning.set(true);
|
isPaused.set(false);
|
shouldStop.set(false);
|
consecutiveFailures = 0;
|
|
try {
|
onlinePollingThread = new Thread(new OnlinePollingTask(), "Online-Polling-Thread");
|
onlinePollingThread.setDaemon(true);
|
onlinePollingThread.start();
|
//System.out.println("在线轮询已启动,周期间隔: " + cycleInterval + "ms, 卡槽间隔: " + slotInterval + "ms");
|
return true;
|
} catch (Exception e) {
|
System.err.println("启动在线轮询线程时发生异常: " + e.getMessage());
|
isRunning.set(false);
|
shouldStop.set(true);
|
return false;
|
}
|
}
|
|
/**
|
* 停止在线轮询 - 修复版本
|
* @return true-停止成功, false-停止失败
|
*/
|
public static boolean stopOnlinePolling() {
|
if (!isRunning.get()) {
|
//System.out.println("在线轮询未在运行");
|
return false;
|
}
|
|
shouldStop.set(true);
|
isRunning.set(false);
|
isPaused.set(false);
|
|
if (onlinePollingThread != null) {
|
onlinePollingThread.interrupt();
|
try {
|
onlinePollingThread.join(3000); // 等待3秒
|
// 检查线程是否还在运行
|
if (onlinePollingThread.isAlive()) {
|
System.err.println("在线轮询线程未在3秒内停止,标记为守护线程并忽略");
|
// 不强制停止,而是确保它是守护线程
|
onlinePollingThread.setDaemon(true);
|
}
|
} catch (InterruptedException e) {
|
System.err.println("停止在线轮询时被中断: " + e.getMessage());
|
Thread.currentThread().interrupt();
|
} catch (Exception e) {
|
System.err.println("停止在线轮询线程时发生异常: " + e.getMessage());
|
} finally {
|
onlinePollingThread = null;
|
}
|
}
|
|
shouldStop.set(false);
|
//System.out.println("在线轮询已停止");
|
return true;
|
}
|
|
/**
|
* 暂停在线轮询
|
* @return true-暂停成功, false-暂停失败
|
*/
|
public static boolean pauseOnlinePolling() {
|
if (!isRunning.get()) {
|
//System.out.println("在线轮询未在运行,无法暂停");
|
return false;
|
}
|
|
if (isPaused.get()) {
|
//System.out.println("在线轮询已经处于暂停状态");
|
return false;
|
}
|
|
isPaused.set(true);
|
//System.out.println("在线轮询已暂停");
|
return true;
|
}
|
|
/**
|
* 恢复在线轮询
|
* @return true-恢复成功, false-恢复失败
|
*/
|
public static boolean resumeOnlinePolling() {
|
if (!isRunning.get()) {
|
//System.out.println("在线轮询未在运行,无法恢复");
|
return false;
|
}
|
|
if (!isPaused.get()) {
|
//System.out.println("在线轮询未处于暂停状态");
|
return false;
|
}
|
|
// 恢复前检查串口连接
|
if (!checkSerialConnectionWithRetry()) {
|
System.err.println("串口未连接,无法恢复在线轮询");
|
return false;
|
}
|
|
isPaused.set(false);
|
synchronized (lunxunzaixian.class) {
|
lunxunzaixian.class.notifyAll(); // 唤醒等待的线程
|
}
|
//System.out.println("在线轮询已恢复");
|
return true;
|
}
|
|
/**
|
* 检查在线轮询状态
|
* @return true-正在运行, false-已停止
|
*/
|
public static boolean isOnlinePolling() {
|
return isRunning.get();
|
}
|
|
/**
|
* 检查是否暂停
|
* @return true-已暂停, false-未暂停
|
*/
|
public static boolean isOnlinePaused() {
|
return isPaused.get();
|
}
|
|
/**
|
* 重新启动在线轮询
|
* @return true-重启成功, false-重启失败
|
*/
|
public static boolean restartOnlinePolling() {
|
stopOnlinePolling();
|
|
// 等待一小段时间确保线程完全停止
|
try {
|
Thread.sleep(200);
|
} catch (InterruptedException e) {
|
Thread.currentThread().interrupt();
|
}
|
|
return startOnlinePolling();
|
}
|
|
/**
|
* 设置轮询间隔参数
|
* @param cycleMs 完整轮询周期间隔(毫秒)
|
* @param slotMs 卡槽间查询间隔(毫秒)
|
*/
|
public static void setPollingIntervals(int cycleMs, int slotMs) {
|
cycleInterval = Math.max(cycleMs, 1000); // 最小1秒
|
slotInterval = Math.max(slotMs, 50); // 最小50毫秒
|
//System.out.println("在线轮询间隔已设置 - 周期间隔: " + cycleInterval + "ms, 卡槽间隔: " + slotInterval + "ms");
|
|
// 如果正在运行,重新启动以应用新的间隔
|
if (isRunning.get()) {
|
restartOnlinePolling();
|
}
|
}
|
|
/**
|
* 获取当前轮询间隔配置
|
* @return 间隔配置字符串
|
*/
|
public static String getPollingIntervals() {
|
return String.format("周期间隔: %dms, 卡槽间隔: %dms", cycleInterval, slotInterval);
|
}
|
|
/**
|
* 获取在线轮询统计信息
|
* @return 统计信息字符串
|
*/
|
public static String getOnlinePollingStats() {
|
int totalSlots = MAX_SLOT - MIN_SLOT + 1;
|
int cardSlots = countCardSlots();
|
|
String status;
|
if (!isRunning.get()) {
|
status = "已停止";
|
} else if (isPaused.get()) {
|
status = "已暂停";
|
} else {
|
status = "运行中";
|
}
|
|
return String.format("在线轮询状态: %s, 有卡卡槽: %d/%d, 周期间隔: %ds, 卡槽间隔: %dms",
|
status, cardSlots, totalSlots, cycleInterval/1000, slotInterval);
|
}
|
|
/**
|
* 统计有卡的卡槽数量
|
* @return 有卡的卡槽数量
|
*/
|
private static int countCardSlots() {
|
if (SlotManager.slotArray == null) {
|
return 0;
|
}
|
|
int count = 0;
|
for (Fkj slot : SlotManager.slotArray) {
|
if (slot != null && "1".equals(slot.getHasCard())) {
|
count++;
|
}
|
}
|
return count;
|
}
|
|
/**
|
* 带重试的串口连接检查
|
*/
|
private static boolean checkSerialConnectionWithRetry() {
|
for (int i = 0; i < 3; i++) {
|
if (lunxun.checkSerialConnection()) {
|
return true;
|
}
|
try {
|
Thread.sleep(1000);
|
} catch (InterruptedException e) {
|
Thread.currentThread().interrupt();
|
return false;
|
}
|
}
|
return false;
|
}
|
|
/**
|
* 在线轮询任务内部类 - 优化版本
|
* 专门轮询有卡的卡槽,优化资源使用
|
*/
|
private static class OnlinePollingTask implements Runnable {
|
@Override
|
public void run() {
|
//System.out.println("在线轮询线程开始运行");
|
|
while (isRunning.get() && !Thread.currentThread().isInterrupted() && !shouldStop.get()) {
|
try {
|
// 检查是否暂停
|
if (isPaused.get()) {
|
synchronized (lunxunzaixian.class) {
|
while (isPaused.get() && isRunning.get() && !shouldStop.get()) {
|
lunxunzaixian.class.wait(1000); // 等待1秒或直到被唤醒
|
}
|
}
|
continue;
|
}
|
|
// 检查串口连接状态
|
if (!checkSerialConnectionWithRetry()) {
|
System.err.println("串口连接断开,暂停在线轮询");
|
pauseOnlinePolling();
|
continue;
|
}
|
|
// 执行一轮有卡卡槽的轮询
|
if (pollCardSlotsOptimized()) {
|
consecutiveFailures = 0; // 重置连续失败计数
|
} else {
|
consecutiveFailures++;
|
if (consecutiveFailures >= MAX_CONSECUTIVE_FAILURES) {
|
System.err.println("连续失败次数过多,暂停在线轮询");
|
pauseOnlinePolling();
|
}
|
}
|
|
// 等待完整周期间隔
|
Thread.sleep(cycleInterval);
|
|
} catch (InterruptedException e) {
|
//System.out.println("在线轮询线程被中断");
|
Thread.currentThread().interrupt();
|
break;
|
} catch (Exception e) {
|
System.err.println("在线轮询过程中发生异常: " + e.getMessage());
|
consecutiveFailures++;
|
|
// 发生异常时等待一段时间再继续
|
try {
|
Thread.sleep(5000);
|
} catch (InterruptedException ie) {
|
Thread.currentThread().interrupt();
|
break;
|
}
|
}
|
}
|
|
//System.out.println("在线轮询线程结束运行");
|
}
|
|
/**
|
* 优化版本:批量轮询有卡卡槽
|
* @return true-轮询成功, false-轮询失败
|
*/
|
private boolean pollCardSlotsOptimized() {
|
if (SlotManager.slotArray == null) {
|
System.err.println("卡槽数组未初始化");
|
return false;
|
}
|
|
List<Integer> cardSlots = new ArrayList<>();
|
|
// 第一阶段:收集所有有卡卡槽
|
for (int i = 0; i < SlotManager.slotArray.length; i++) {
|
if (!isRunning.get() || Thread.currentThread().isInterrupted() || shouldStop.get()) {
|
break;
|
}
|
|
Fkj slot = SlotManager.slotArray[i];
|
if (slot != null && "1".equals(slot.getHasCard())) {
|
cardSlots.add(i + 1);
|
}
|
}
|
|
if (cardSlots.isEmpty()) {
|
if (lunxun.DEBUG_ENABLED) {
|
//System.out.println("没有找到有卡的卡槽");
|
}
|
return true;
|
}
|
|
int polledCount = 0;
|
int totalCardSlots = cardSlots.size();
|
|
// 第二阶段:批量查询有卡卡槽
|
for (int i = 0; i < cardSlots.size(); i += BATCH_SIZE) {
|
if (!isRunning.get() || Thread.currentThread().isInterrupted() || shouldStop.get()) {
|
break;
|
}
|
|
int end = Math.min(i + BATCH_SIZE, cardSlots.size());
|
List<Integer> batch = cardSlots.subList(i, end);
|
|
// 批次内查询
|
for (int slotNumber : batch) {
|
if (sendQueryToCardSlot(slotNumber)) {
|
polledCount++;
|
}
|
}
|
|
// 批次间间隔
|
if (end < cardSlots.size()) {
|
try {
|
Thread.sleep(slotInterval * BATCH_SIZE);
|
} catch (InterruptedException e) {
|
Thread.currentThread().interrupt();
|
break;
|
}
|
}
|
}
|
|
if (polledCount > 0 && lunxun.DEBUG_ENABLED) {
|
//System.out.println("在线轮询完成,成功查询 " + polledCount + "/" + totalCardSlots + " 个有卡卡槽");
|
}
|
|
return polledCount > 0;
|
}
|
|
/**
|
* 向指定有卡卡槽发送查询指令
|
* @param slotNumber 卡槽编号
|
* @return true-发送成功, false-发送失败
|
*/
|
private boolean sendQueryToCardSlot(int slotNumber) {
|
try {
|
// 使用原有的立即查询功能
|
boolean result = lunxun.sendImmediateQuery(slotNumber);
|
|
if (result) {
|
// 记录调试信息(减少输出频率)
|
if (lunxun.DEBUG_ENABLED && (slotNumber == 1 || slotNumber % 10 == 0)) {
|
//System.out.println("在线轮询 - 查询有卡卡槽 " + slotNumber);
|
}
|
return true;
|
} else {
|
System.err.println("在线轮询 - 查询有卡卡槽 " + slotNumber + " 失败");
|
return false;
|
}
|
|
} catch (Exception e) {
|
System.err.println("在线轮询 - 查询有卡卡槽 " + slotNumber + " 时发生异常: " + e.getMessage());
|
return false;
|
}
|
}
|
}
|
|
/**
|
* 手动触发立即轮询(不等待周期)- 优化版本
|
* @return 成功查询的卡槽数量
|
*/
|
public static int triggerImmediatePolling() {
|
if (!isRunning.get() || isPaused.get()) {
|
System.err.println("在线轮询未运行或已暂停,无法立即轮询");
|
return 0;
|
}
|
|
if (!checkSerialConnectionWithRetry()) {
|
System.err.println("串口未连接,无法执行立即轮询");
|
return 0;
|
}
|
|
//System.out.println("开始立即轮询有卡卡槽...");
|
|
OnlinePollingTask task = new OnlinePollingTask();
|
|
// 使用新的批量轮询方法
|
int cardSlotCount = countCardSlots();
|
|
// 在新线程中执行立即轮询,避免阻塞当前线程
|
Thread immediateThread = new Thread(() -> {
|
try {
|
task.pollCardSlotsOptimized();
|
} catch (Exception e) {
|
System.err.println("立即轮询过程中发生异常: " + e.getMessage());
|
}
|
}, "Immediate-Online-Polling");
|
|
immediateThread.setDaemon(true);
|
immediateThread.start();
|
|
return cardSlotCount;
|
}
|
|
/**
|
* 设置在线轮询暂停状态(供其他类调用)
|
* @param paused true-暂停轮询, false-恢复轮询
|
* @return true-设置成功, false-设置失败
|
*/
|
public static boolean setOnlinePollingPaused(boolean paused) {
|
if (!isRunning.get()) {
|
//System.out.println("在线轮询未在运行,无法设置暂停状态");
|
return false;
|
}
|
|
if (paused) {
|
return pauseOnlinePolling();
|
} else {
|
return resumeOnlinePolling();
|
}
|
}
|
|
/**
|
* 获取性能统计信息
|
*/
|
public static String getPerformanceStats() {
|
return String.format("批量大小: %d, 周期间隔: %dms, 卡槽间隔: %dms",
|
BATCH_SIZE, cycleInterval, slotInterval);
|
}
|
}
|