fix(ft546): serialize shuttle reader lifecycle

This commit is contained in:
zgw
2026-08-11 12:10:24 +08:00
parent 46302c0de1
commit edafe7af94
3 changed files with 151 additions and 18 deletions

View File

@@ -30,6 +30,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -66,8 +67,10 @@ public class ScheduleThread {
@Autowired
private Ft546SrgvRuntimeFactory srgvRuntimeFactory;
private boolean isRun = false;
private boolean isRun2 = false;
private volatile boolean isRun = false;
private volatile boolean isRun2 = false;
private static final long THREAD_STOP_TIMEOUT_MS = 5000L;
/**
* 项目初始化启动
@@ -171,16 +174,21 @@ public class ScheduleThread {
/**
* 开始线程
*/
public void startAllThread() {
plcSsjReadCustomThread.getThread().start();
for (CustomThread<PlcSrgvRead> reader
: plcSrgvReadCustomThreads.values()) {
reader.getThread().start();
public synchronized void startAllThread() {
if (isRun) {
return;
}
List<Thread> readerThreads = requireFactReaderThreads();
for (Thread readerThread : readerThreads) {
if (readerThread.getState() != Thread.State.NEW) {
throw new IllegalStateException(
"PLC fact reader cannot be restarted: "
+ readerThread.getName());
}
}
for (Thread readerThread : readerThreads) {
readerThread.start();
}
plcTsjReadCustomThread.getThread().start();
plcCdzReadCustomThread.getThread().start();
isRun = true;
}
@@ -200,14 +208,18 @@ public class ScheduleThread {
/**
* 停止线程
*/
public void stopAllThread() {
plcSsjReadCustomThread.runnable.isRun = false;
for (CustomThread<PlcSrgvRead> reader
: plcSrgvReadCustomThreads.values()) {
reader.runnable.isRun = false;
public synchronized void stopAllThread() {
if (!isRun) {
return;
}
List<Thread> readerThreads = currentFactReaderThreads();
signalFactReadersToStop();
isRun = false;
awaitFactReadersStopped(readerThreads);
plcSrgvReadCustomThreads.clear();
deviceRuntimeRegistry.clear();
if (deviceRuntimeRegistry != null) {
deviceRuntimeRegistry.clear();
}
// plcDdj1ReadCustomThread.runnable.isRun = false;
/* plcDdj2ReadCustomThread.runnable.isRun = false;
plcDdj3ReadCustomThread.runnable.isRun = false;
@@ -215,7 +227,95 @@ public class ScheduleThread {
plcDdj5ReadCustomThread.runnable.isRun = false;
plcDdj6ReadCustomThread.runnable.isRun = false;*/
plcReadInit();
isRun = false;
}
private List<Thread> requireFactReaderThreads() {
List<Thread> threads = new ArrayList<Thread>();
threads.add(requireThread(plcSsjReadCustomThread,
"conveyor fact reader"));
for (Map.Entry<String, CustomThread<PlcSrgvRead>> entry
: plcSrgvReadCustomThreads.entrySet()) {
threads.add(requireThread(entry.getValue(),
"shuttle fact reader " + entry.getKey()));
}
threads.add(requireThread(plcTsjReadCustomThread,
"lift fact reader"));
threads.add(requireThread(plcCdzReadCustomThread,
"charger fact reader"));
return threads;
}
private List<Thread> currentFactReaderThreads() {
List<Thread> threads = new ArrayList<Thread>();
addThreadIfPresent(threads, plcSsjReadCustomThread);
for (CustomThread<PlcSrgvRead> reader
: plcSrgvReadCustomThreads.values()) {
addThreadIfPresent(threads, reader);
}
addThreadIfPresent(threads, plcTsjReadCustomThread);
addThreadIfPresent(threads, plcCdzReadCustomThread);
return threads;
}
private void signalFactReadersToStop() {
if (plcSsjReadCustomThread != null
&& plcSsjReadCustomThread.runnable != null) {
plcSsjReadCustomThread.runnable.isRun = false;
}
for (CustomThread<PlcSrgvRead> reader
: plcSrgvReadCustomThreads.values()) {
if (reader != null && reader.runnable != null) {
reader.runnable.isRun = false;
}
}
if (plcTsjReadCustomThread != null
&& plcTsjReadCustomThread.runnable != null) {
plcTsjReadCustomThread.runnable.isRun = false;
}
if (plcCdzReadCustomThread != null
&& plcCdzReadCustomThread.runnable != null) {
plcCdzReadCustomThread.runnable.isRun = false;
}
}
private void awaitFactReadersStopped(List<Thread> readerThreads) {
long deadline = System.currentTimeMillis() + THREAD_STOP_TIMEOUT_MS;
for (Thread readerThread : readerThreads) {
long remaining = deadline - System.currentTimeMillis();
if (remaining <= 0L) {
break;
}
try {
readerThread.join(remaining);
} catch (InterruptedException interrupted) {
Thread.currentThread().interrupt();
throw new IllegalStateException(
"interrupted while stopping PLC fact readers",
interrupted);
}
}
for (Thread readerThread : readerThreads) {
if (readerThread.isAlive()) {
throw new IllegalStateException(
"PLC fact reader did not stop: "
+ readerThread.getName());
}
}
}
private static Thread requireThread(CustomThread<?> customThread,
String name) {
if (customThread == null || customThread.getThread() == null) {
throw new IllegalStateException(name + " is not initialized");
}
return customThread.getThread();
}
private static void addThreadIfPresent(List<Thread> threads,
CustomThread<?> customThread) {
if (customThread != null && customThread.getThread() != null) {
threads.add(customThread.getThread());
}
}
/**