fix:线程阻塞问题处理2

This commit is contained in:
2024-08-16 10:18:40 +08:00
parent 1c88c2267b
commit f008173066
4 changed files with 87 additions and 11 deletions

View File

@@ -210,7 +210,6 @@ public class BeltConveyorDeviceDriver extends AbstractOpcDeviceDriver implements
JSONObject led_message = null; JSONObject led_message = null;
@Override @Override
public Device getDevice() { public Device getDevice() {
return this.device; return this.device;
@@ -245,7 +244,7 @@ public class BeltConveyorDeviceDriver extends AbstractOpcDeviceDriver implements
} }
if (move != 0 && task > 0) { if (move != 0 && task > 0) {
if (null!=inst) { if (null != inst) {
inst_message = "指令号:" + inst.getInstruction_code() + " " + inst.getStart_point_code() + "->" + inst.getNext_point_code(); inst_message = "指令号:" + inst.getInstruction_code() + " " + inst.getStart_point_code() + "->" + inst.getNext_point_code();
} }
CompletableFuture.runAsync(() -> { CompletableFuture.runAsync(() -> {
@@ -261,7 +260,7 @@ public class BeltConveyorDeviceDriver extends AbstractOpcDeviceDriver implements
if (mode == 8 && !requireSucess) { if (mode == 8 && !requireSucess) {
if (container_type == 0) { if (container_type == 0) {
message = "托盘类型为空"; message = "托盘类型为空";
}else { } else {
applyEmptyTask(StorageTypeEnum.DISKS_OUT.getType(), mode); applyEmptyTask(StorageTypeEnum.DISKS_OUT.getType(), mode);
} }
@@ -332,7 +331,7 @@ public class BeltConveyorDeviceDriver extends AbstractOpcDeviceDriver implements
this.iserror = true; this.iserror = true;
LuceneLogDto logDto = LuceneLogDto.builder() LuceneLogDto logDto = LuceneLogDto.builder()
.device_code(device_code) .device_code(device_code)
.content(this.device_code+ "读取信号值时出现异常:" + var17.getMessage() + ",this.itemProtocol is null") .content(this.device_code + "读取信号值时出现异常:" + var17.getMessage() + ",this.itemProtocol is null")
.build(); .build();
logDto.setLog_level(4); logDto.setLog_level(4);
luceneExecuteLogService.deviceExecuteLog(logDto); luceneExecuteLogService.deviceExecuteLog(logDto);
@@ -493,7 +492,7 @@ public class BeltConveyorDeviceDriver extends AbstractOpcDeviceDriver implements
} else { } else {
//查看是否存在输送线到对接为的指令 //查看是否存在输送线到对接为的指令
Instruction byNextDeviceCodeFromCache = instructionService.findByNextDeviceCodeFromCache(this.device_code); Instruction byNextDeviceCodeFromCache = instructionService.findByNextDeviceCodeFromCache(this.device_code);
if (ObjectUtil.isNotEmpty(byNextDeviceCodeFromCache)){ if (ObjectUtil.isNotEmpty(byNextDeviceCodeFromCache)) {
LuceneLogDto logDto = LuceneLogDto.builder() LuceneLogDto logDto = LuceneLogDto.builder()
.device_code(device_code) .device_code(device_code)
.content("存在堆垛机对接为的指令") .content("存在堆垛机对接为的指令")
@@ -561,7 +560,7 @@ public class BeltConveyorDeviceDriver extends AbstractOpcDeviceDriver implements
TaskDto taskdto = taskserver.findByStartCodeAndReady(device_code); TaskDto taskdto = taskserver.findByStartCodeAndReady(device_code);
if (ObjectUtil.isNotNull(taskdto)) { if (ObjectUtil.isNotNull(taskdto)) {
//移除行架任务 //移除行架任务
if (taskdto.getTask_type().equals(TaskTypeEnum.Truss_Task.getIndex())){ if (taskdto.getTask_type().equals(TaskTypeEnum.Truss_Task.getIndex())) {
return false; return false;
} }
//判断指令的起点和当前的设备号相同 //判断指令的起点和当前的设备号相同

View File

@@ -1,8 +1,12 @@
package org.nl.acs.opc; package org.nl.acs.opc;
import javax.annotation.Resource;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
/** /**
* @author LENOVO * @author LENOVO
@@ -11,6 +15,7 @@ public abstract class BlockedRunable implements Runnable {
private String threadName; private String threadName;
private Date startTime; private Date startTime;
private Map<String, BlockedRunable> index = new HashMap(); private Map<String, BlockedRunable> index = new HashMap();
// ExecutorService executor = Executors.newSingleThreadExecutor();
public BlockedRunable() { public BlockedRunable() {
} }
@@ -25,6 +30,9 @@ public abstract class BlockedRunable implements Runnable {
*/ */
public abstract String getCode(); public abstract String getCode();
/** /**
* subRun * subRun
* @throws Exception * @throws Exception

View File

@@ -1,11 +1,14 @@
package org.nl.acs.opc; package org.nl.acs.opc;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.dromara.dynamictp.core.DtpRegistry;
import org.nl.acs.auto.run.AbstractAutoRunnable; import org.nl.acs.auto.run.AbstractAutoRunnable;
import org.nl.acs.auto.run.AutoRunService; import org.nl.acs.auto.run.AutoRunService;
import org.nl.acs.device_driver.driver.ExecutableDeviceDriver; import org.nl.acs.device_driver.driver.ExecutableDeviceDriver;
import org.nl.acs.instruction.service.InstructionService;
import org.nl.acs.udw.UnifiedDataAccessor; import org.nl.acs.udw.UnifiedDataAccessor;
import org.nl.acs.udw.UnifiedDataAccessorFactory; import org.nl.acs.udw.UnifiedDataAccessorFactory;
import org.nl.config.SpringContextHolder;
import org.nl.config.thread.TheadFactoryName; import org.nl.config.thread.TheadFactoryName;
import org.nl.config.thread.ThreadPoolExecutorUtil; import org.nl.config.thread.ThreadPoolExecutorUtil;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@@ -38,6 +41,8 @@ public class DeviceExecuteAutoRun extends AbstractAutoRunnable {
@Resource @Resource
private ThreadPoolExecutor executorService; private ThreadPoolExecutor executorService;
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(30);
Map<String, BlockedRunable> runs; Map<String, BlockedRunable> runs;
public DeviceExecuteAutoRun() { public DeviceExecuteAutoRun() {
@@ -114,10 +119,35 @@ public class DeviceExecuteAutoRun extends AbstractAutoRunnable {
//不包含正在执行的线程,则进行执行 //不包含正在执行的线程,则进行执行
if (!this.runs.keySet().contains(deviceDriver.getDeviceCode())) { if (!this.runs.keySet().contains(deviceDriver.getDeviceCode())) {
BlockedRunable runnable = new BlockedRunable() { BlockedRunable runnable = new BlockedRunable() {
@Override @Override
public void subRun() throws Exception { public void subRun() throws Exception {
deviceDriver.executeAuto(); deviceDriver.executeAuto();
/* ThreadPoolExecutor executor= DtpRegistry.getDtpExecutor("dtpExecutor1");
Future<?> submit = executor.submit(() -> {
try {
deviceDriver.executeAuto();
} catch (Exception e) {
throw new RuntimeException(e);
}
});
try {
// 设置超时时间为 15 秒,如果任务超时,抛出 TimeoutException
submit.get(10, TimeUnit.SECONDS);
System.out.println();
} catch (TimeoutException e) {
System.out.println("任务超时,取消任务!");
// 使用反射获取 FutureTask 中的线程,并使用 Thread.stop() 强制终止
Field runnerField = submit.getClass().getDeclaredField("runner");
runnerField.setAccessible(true);
Thread runnerThread = (Thread) runnerField.get(submit);
if (runnerThread != null) {
runnerThread.stop(); // 强制终止线程(不推荐)
}
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}*/
} }
@Override @Override
@@ -144,7 +174,7 @@ public class DeviceExecuteAutoRun extends AbstractAutoRunnable {
//plc断连后强制终止线程 //plc断连后强制终止线程
try { /* try {
// 设置超时时间为 15 秒,如果任务超时,抛出 TimeoutException // 设置超时时间为 15 秒,如果任务超时,抛出 TimeoutException
future.get(15, TimeUnit.SECONDS); future.get(15, TimeUnit.SECONDS);
} catch (TimeoutException e) { } catch (TimeoutException e) {
@@ -159,7 +189,42 @@ public class DeviceExecuteAutoRun extends AbstractAutoRunnable {
} catch (InterruptedException | ExecutionException e) { } catch (InterruptedException | ExecutionException e) {
e.printStackTrace(); e.printStackTrace();
} }*/
// 使用调度器在超时后取消任务
scheduler.schedule(() -> {
if (!future.isDone()) {
// future.cancel(true); // 尝试中断任务
// Field runnerField = null;
// try {
// runnerField = future.getClass().getDeclaredField("runner");
// runnerField.setAccessible(true);
// Thread runnerThread = (Thread) runnerField.get(future);
// if (runnerThread != null) {
// runnerThread.stop(); // 强制终止线程(不推荐)
// }
// } catch (Exception e) {
// throw new RuntimeException(e);
// }
try {
// 设置超时时间为 30 秒,如果任务超时,抛出 TimeoutException
future.get(5, TimeUnit.SECONDS);
} catch (TimeoutException e) {
System.out.println("任务超时,取消任务!");
// 超时后取消任务,并设置为 true 以中断执行中的线程
future.cancel(true);
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
}, 5, TimeUnit.SECONDS); // 设置超时时间为10秒
} }

View File

@@ -4,6 +4,7 @@ import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.TimeInterval; import cn.hutool.core.date.TimeInterval;
import cn.hutool.core.util.NumberUtil; import cn.hutool.core.util.NumberUtil;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.dromara.dynamictp.core.DtpRegistry;
import org.jinterop.dcom.common.JIException; import org.jinterop.dcom.common.JIException;
import org.jinterop.dcom.core.*; import org.jinterop.dcom.core.*;
import org.nl.acs.device_driver.driver.ItemValue; import org.nl.acs.device_driver.driver.ItemValue;
@@ -13,11 +14,12 @@ import org.nl.config.language.LangProcess;
import org.openscada.opc.lib.common.ConnectionInformation; import org.openscada.opc.lib.common.ConnectionInformation;
import org.openscada.opc.lib.da.*; import org.openscada.opc.lib.da.*;
import java.lang.reflect.Field;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.Executors; import java.util.concurrent.*;
/** /**
* @author 20220102CG\noblelift * @author 20220102CG\noblelift
@@ -42,6 +44,7 @@ public class OpcUtl {
public static void writeValue(Group group, WriteRequest... requests) throws BadRequestException { public static void writeValue(Group group, WriteRequest... requests) throws BadRequestException {
try { try {
Map<Item, Integer> e = null; Map<Item, Integer> e = null;
try { try {
e = group.write(requests); e = group.write(requests);
// group.write(requests); // group.write(requests);
@@ -230,7 +233,8 @@ public class OpcUtl {
} }
} }
public static Server getAutoServer(String host, String clsid, String user, String password, String domain) throws BadRequestException { public static Server getAutoServer(String host, String clsid, String user, String password, String domain) throws
BadRequestException {
checkTimeout(); checkTimeout();
Server server = null; Server server = null;
server = new Server(getConnection(host, clsid, user, password, domain), Executors.newSingleThreadScheduledExecutor()); server = new Server(getConnection(host, clsid, user, password, domain), Executors.newSingleThreadScheduledExecutor());