From 4fcbff9f29fb187c4db25ce78b77059d6c0a010c Mon Sep 17 00:00:00 2001 From: "USER-20220102CG\\noblelift" <546428999@qq.com> Date: Sun, 8 Oct 2023 17:08:28 +0800 Subject: [PATCH] =?UTF-8?q?add=20=E5=A2=9E=E5=8A=A0=E5=BF=83=E8=B7=B3?= =?UTF-8?q?=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/org/nl/acs/AcsConfig.java | 3 + .../org/nl/acs/auto/run/SystemConfig.java | 2 + .../src/main/java/org/nl/acs/device.xls | Bin 236032 -> 220160 bytes .../HeartbeatableDeviceDriver.java | 10 + .../ConveyorPressStationDeviceDriver.java | 71 +- .../DeviceHeartbeatExecuteAutoRun.java | 92 ++ .../org/nl/acs/heartbeat/HeartbeatConfig.java | 10 + .../HeartbeatOfflineCheckerAutoRun.java | 56 ++ .../acs/heartbeat/dto/HeartbeatManageDto.java | 38 +- .../HeartbeatManageServiceimpl.java | 10 +- .../HeartbeatUnifiedServiceimpl.java | 85 +- .../nl/acs/opc/BlockedThreadPoolPolicy.java | 25 + .../java/org/nl/acs/opc/DeviceManageDto.java | 2 +- .../opc/IncreasedBlokdedThreadPoolPolicy.java | 22 + .../IncreasedRejectedExecutionHandler.java | 5 + .../acs/opc/IncreasedThreadPoolExecutor.java | 943 ++++++++++++++++++ .../java/org/nl/acs/opc/ThreadPoolUtl.java | 71 ++ 17 files changed, 1403 insertions(+), 42 deletions(-) create mode 100644 acs/nladmin-system/src/main/java/org/nl/acs/device_driver/HeartbeatableDeviceDriver.java create mode 100644 acs/nladmin-system/src/main/java/org/nl/acs/heartbeat/DeviceHeartbeatExecuteAutoRun.java create mode 100644 acs/nladmin-system/src/main/java/org/nl/acs/heartbeat/HeartbeatConfig.java create mode 100644 acs/nladmin-system/src/main/java/org/nl/acs/heartbeat/HeartbeatOfflineCheckerAutoRun.java create mode 100644 acs/nladmin-system/src/main/java/org/nl/acs/opc/BlockedThreadPoolPolicy.java create mode 100644 acs/nladmin-system/src/main/java/org/nl/acs/opc/IncreasedBlokdedThreadPoolPolicy.java create mode 100644 acs/nladmin-system/src/main/java/org/nl/acs/opc/IncreasedRejectedExecutionHandler.java create mode 100644 acs/nladmin-system/src/main/java/org/nl/acs/opc/IncreasedThreadPoolExecutor.java create mode 100644 acs/nladmin-system/src/main/java/org/nl/acs/opc/ThreadPoolUtl.java diff --git a/acs/nladmin-system/src/main/java/org/nl/acs/AcsConfig.java b/acs/nladmin-system/src/main/java/org/nl/acs/AcsConfig.java index 6b05bc5..b80befc 100644 --- a/acs/nladmin-system/src/main/java/org/nl/acs/AcsConfig.java +++ b/acs/nladmin-system/src/main/java/org/nl/acs/AcsConfig.java @@ -50,4 +50,7 @@ public interface AcsConfig { String AutoCleanDays = "AutoCleanDays"; //最大任务下发时间 String MAXSENDTASKTIME = "maxSendTaskTime"; + + //是否模拟在线 + String fork_online = "fork_online"; } diff --git a/acs/nladmin-system/src/main/java/org/nl/acs/auto/run/SystemConfig.java b/acs/nladmin-system/src/main/java/org/nl/acs/auto/run/SystemConfig.java index 93653e3..59ee889 100644 --- a/acs/nladmin-system/src/main/java/org/nl/acs/auto/run/SystemConfig.java +++ b/acs/nladmin-system/src/main/java/org/nl/acs/auto/run/SystemConfig.java @@ -9,4 +9,6 @@ public class SystemConfig { public static Integer sequence_initial_value = Integer.valueOf(1); //@DictionaryItem(description = "主线程是否自动开启选项") public static Boolean thread_auto_run = Boolean.valueOf(true); + // description = "不启用心跳功能" + public static Boolean heartbeat_no_use= Boolean.valueOf(false); } diff --git a/acs/nladmin-system/src/main/java/org/nl/acs/device.xls b/acs/nladmin-system/src/main/java/org/nl/acs/device.xls index 427b90b84f37195128c8413ebe8754a4da2dd5bc..7e2a1835684c49bf4c3f81ee17b8e93d1e10ef62 100644 GIT binary patch delta 27320 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 delta 33362 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 Ltz0m`e#7=ZOd&`g diff --git a/acs/nladmin-system/src/main/java/org/nl/acs/device_driver/HeartbeatableDeviceDriver.java b/acs/nladmin-system/src/main/java/org/nl/acs/device_driver/HeartbeatableDeviceDriver.java new file mode 100644 index 0000000..e223e30 --- /dev/null +++ b/acs/nladmin-system/src/main/java/org/nl/acs/device_driver/HeartbeatableDeviceDriver.java @@ -0,0 +1,10 @@ +package org.nl.acs.device_driver; + +public interface HeartbeatableDeviceDriver extends DeviceDriver { + default void checkHeartbeat() { + } + + default boolean isOnline() { + return false; + } +} diff --git a/acs/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/conveyor_press_station/ConveyorPressStationDeviceDriver.java b/acs/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/conveyor_press_station/ConveyorPressStationDeviceDriver.java index 107ac95..dcba32a 100644 --- a/acs/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/conveyor_press_station/ConveyorPressStationDeviceDriver.java +++ b/acs/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/conveyor_press_station/ConveyorPressStationDeviceDriver.java @@ -8,27 +8,32 @@ import lombok.Getter; import lombok.RequiredArgsConstructor; import lombok.Setter; import lombok.extern.slf4j.Slf4j; +import org.nl.acs.AcsConfig; import org.nl.acs.device.device_driver.standard_inspect.ReadUtil; import org.nl.acs.device.service.DeviceService; -import org.nl.acs.device_driver.DeviceDriver; -import org.nl.acs.device_driver.RequestMethodEnum; -import org.nl.acs.device_driver.RouteableDeviceDriver; -import org.nl.acs.device_driver.StandardRequestMethod; +import org.nl.acs.device_driver.*; import org.nl.acs.device_driver.driver.AbstractOpcDeviceDriver; import org.nl.acs.device_driver.driver.ExecutableDeviceDriver; import org.nl.acs.ext.wms.data.AcsToWmsData.applyTask.ApplyTaskRequest; import org.nl.acs.ext.wms.data.AcsToWmsData.applyTask.ApplyTaskResponse; import org.nl.acs.ext.wms.data.Resp; import org.nl.acs.ext.wms.service.AcsToWmsService; +import org.nl.acs.heartbeat.HeartbeatEvent; +import org.nl.acs.heartbeat.dto.HeartbeatManageDto; +import org.nl.acs.heartbeat.enums.HeartbeatType; +import org.nl.acs.heartbeat.service.HeartbeatUnifiedService; import org.nl.acs.instruction.service.InstructionService; import org.nl.acs.instruction.service.dto.Instruction; import org.nl.acs.log.service.DeviceExecuteLogService; import org.nl.acs.monitor.DeviceStageMonitor; import org.nl.acs.opc.Device; +import org.nl.acs.opc.ObjectUtl; import org.nl.acs.route.service.RouteLineService; import org.nl.acs.task.service.TaskService; import org.nl.modules.lucene.service.LuceneExecuteLogService; import org.nl.modules.lucene.service.dto.LuceneLogDto; +import org.nl.modules.system.service.ParamService; +import org.nl.modules.system.service.impl.ParamServiceImpl; import org.nl.modules.wql.util.SpringContextHolder; import org.openscada.opc.lib.da.Server; @@ -45,7 +50,7 @@ import java.util.Map; @Getter @Setter @RequiredArgsConstructor -public class ConveyorPressStationDeviceDriver extends AbstractOpcDeviceDriver implements DeviceDriver, ExecutableDeviceDriver, RouteableDeviceDriver, DeviceStageMonitor, StandardRequestMethod { +public class ConveyorPressStationDeviceDriver extends AbstractOpcDeviceDriver implements DeviceDriver, ExecutableDeviceDriver, RouteableDeviceDriver, DeviceStageMonitor, StandardRequestMethod, HeartbeatableDeviceDriver { protected ItemProtocol itemProtocol = new ItemProtocol(this); LuceneExecuteLogService lucene = SpringContextHolder.getBean("luceneExecuteLogServiceImpl"); @@ -62,6 +67,12 @@ public class ConveyorPressStationDeviceDriver extends AbstractOpcDeviceDriver im AcsToWmsService acsToWmsService = SpringContextHolder.getBean("acsToWmsServiceImpl"); + HeartbeatUnifiedService heartbeatUnifiedService = SpringContextHolder.getBean(HeartbeatUnifiedService.class); + + ParamService paramService = SpringContextHolder.getBean(ParamServiceImpl.class); + + String fork_online = paramService.findByCode(AcsConfig.fork_online).getValue(); + String device_code; int mode = 0; int error = 0; @@ -435,7 +446,7 @@ public class ConveyorPressStationDeviceDriver extends AbstractOpcDeviceDriver im jo.put("weight", weight); jo.put("barcode", barcode); jo.put("isError", iserror); - jo.put("isOnline", isonline); + jo.put("isOnline", isOnline()); jo.put("hasGoods", hasGoods); jo.put("message", message); return jo; @@ -808,4 +819,52 @@ public class ConveyorPressStationDeviceDriver extends AbstractOpcDeviceDriver im return false; } } + + public void checkHeartbeat() { + Integer heartbeat_temp = null; + + try { + heartbeat_temp = this.itemProtocol.getHeartbeat(); + } catch (Exception var3) { + } + + if (!ObjectUtl.isEquals(this.heartbeat_tag, heartbeat_temp)) { + if (heartbeat_temp != null && this.heartbeat_tag != null) { + System.out.println("check heartbeaet!"); + HeartbeatEvent event = new HeartbeatEvent(); + event.setResource_code(this.getDeviceCode()); + event.setResource_name(this.getDevice().getDevice_name()); +// heartbeatUnifiedService.onlineChecker(event); +// DeviceHeartbeatEvent event = new DeviceHeartbeatEvent(); +// event.setResource_code(this.getDeviceCode()); +// if (this.getDevice() != null) { +// event.setResource_name(this.getDevice().getName()); +// } +// ApplicationEventPublisher.trigger(event); + + + } + + this.heartbeat_tag = heartbeat_temp; + } + + } + + public boolean isOnline() { +// long begin = System.currentTimeMillis(); + if (StrUtil.equals(paramService.findByCode(AcsConfig.fork_online).getValue(),"1")) { +// long end = System.currentTimeMillis(); +// long duration = end - begin; +// System.out.println("设备:"+device_code+",耗时:"+ duration); + return true; + } else { + HeartbeatManageDto heartbeat = heartbeatUnifiedService.findByResourceCode(this.getDeviceCode()); +// long end = System.currentTimeMillis(); +// long duration = end - begin; +// System.out.println("设备:"+device_code+",耗时:"+ duration); + return heartbeat != null && ObjectUtl.isEquals(heartbeat.getStatus(), HeartbeatType.online); + } + + + } } diff --git a/acs/nladmin-system/src/main/java/org/nl/acs/heartbeat/DeviceHeartbeatExecuteAutoRun.java b/acs/nladmin-system/src/main/java/org/nl/acs/heartbeat/DeviceHeartbeatExecuteAutoRun.java new file mode 100644 index 0000000..846d986 --- /dev/null +++ b/acs/nladmin-system/src/main/java/org/nl/acs/heartbeat/DeviceHeartbeatExecuteAutoRun.java @@ -0,0 +1,92 @@ +package org.nl.acs.heartbeat; + +import lombok.extern.slf4j.Slf4j; +import org.nl.acs.auto.run.AbstractAutoRunnable; +import org.nl.acs.auto.run.SystemConfig; +import org.nl.acs.device_driver.HeartbeatableDeviceDriver; +import org.nl.acs.opc.*; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.*; +import java.util.concurrent.ExecutorService; + +@Slf4j +@Component +public class DeviceHeartbeatExecuteAutoRun extends AbstractAutoRunnable { + + @Autowired + DeviceAppService deviceAppService; + int initial_thread = 2; + int max_thread = 10; + int cache_thread = 5; + int loop_time_millions = 300; + ExecutorService executorService; + Map runs; + + public DeviceHeartbeatExecuteAutoRun() { + this.executorService = ThreadPoolUtl.newIncreasedBlockedThreadPool(this.initial_thread, this.max_thread, this.cache_thread); + this.runs = new LinkedHashMap(); + this.runs = Collections.synchronizedMap(this.runs); + } + + public String getCode() { + return DeviceHeartbeatExecuteAutoRun.class.getSimpleName(); + } + + public String getName() { + return "设备在线监听"; + } + + public void autoRun() { + while(true) { + ThreadUtl.sleep((long)this.loop_time_millions); + if (SystemConfig.heartbeat_no_use) { + return; + } + if(!DeviceOpcSynchronizeAutoRun.isRun){ + return; + } + + List deviceDrivers = this.deviceAppService.findDeviceDriver(HeartbeatableDeviceDriver.class); + Iterator var2 = deviceDrivers.iterator(); + + while(var2.hasNext()) { + final HeartbeatableDeviceDriver deviceDriver = (HeartbeatableDeviceDriver)var2.next(); + if (deviceDriver.getDevice().getIs_config() != null && deviceDriver.getDevice().getIs_config() && !this.runs.keySet().contains(deviceDriver.getDeviceCode())) { + BlockedRunable runable = new BlockedRunable() { + public void subRun() { + deviceDriver.checkHeartbeat(); + } + + public String getCode() { + return deviceDriver.getDeviceCode(); + } + }; + if (!this.runs.keySet().contains(deviceDriver.getDeviceCode())) { + this.runs.put(deviceDriver.getDeviceCode(), runable); + } + + runable.setIndex(this.runs); + this.executorService.submit(runable); + } + } + } + } + + public void after() { + this.executorService.shutdownNow(); + this.executorService = ThreadPoolUtl.newIncreasedBlockedThreadPool(this.initial_thread, this.max_thread, this.cache_thread); + this.runs = new LinkedHashMap(); + this.runs = Collections.synchronizedMap(this.runs); + } + + public ExecutorService getExecutorService() { + return this.executorService; + } + + public Map getRuns() { + return this.runs; + } + +} diff --git a/acs/nladmin-system/src/main/java/org/nl/acs/heartbeat/HeartbeatConfig.java b/acs/nladmin-system/src/main/java/org/nl/acs/heartbeat/HeartbeatConfig.java new file mode 100644 index 0000000..b9d0016 --- /dev/null +++ b/acs/nladmin-system/src/main/java/org/nl/acs/heartbeat/HeartbeatConfig.java @@ -0,0 +1,10 @@ +package org.nl.acs.heartbeat; + +public class HeartbeatConfig { + + /** + * 最大心跳时常 + */ + public static Integer max_alive_time_millions = 1000 * 30; + +} diff --git a/acs/nladmin-system/src/main/java/org/nl/acs/heartbeat/HeartbeatOfflineCheckerAutoRun.java b/acs/nladmin-system/src/main/java/org/nl/acs/heartbeat/HeartbeatOfflineCheckerAutoRun.java new file mode 100644 index 0000000..0b3fb06 --- /dev/null +++ b/acs/nladmin-system/src/main/java/org/nl/acs/heartbeat/HeartbeatOfflineCheckerAutoRun.java @@ -0,0 +1,56 @@ +package org.nl.acs.heartbeat; + +import lombok.extern.slf4j.Slf4j; +import org.nl.acs.auto.run.AbstractAutoRunnable; +import org.nl.acs.auto.run.AutoRunService; +import org.nl.acs.heartbeat.service.HeartbeatUnifiedService; +import org.nl.acs.heartbeat.service_impl.HeartbeatUnifiedServiceimpl; +import org.nl.acs.opc.ThreadUtl; +import org.nl.modules.wql.util.SpringContextHolder; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.Date; + +@Slf4j +@Component +public class HeartbeatOfflineCheckerAutoRun extends AbstractAutoRunnable { + @Autowired + AutoRunService autoRunService; + + private int recordTimeOut = 10000; + private Date recordTime; + int offline_loop_time_millions = 1000; + boolean heartbeat_no_use =false; + public HeartbeatOfflineCheckerAutoRun() { + this.recordTime = new Date((new Date()).getTime() - (long)this.recordTimeOut); + } + + public String getCode() { + return HeartbeatOfflineCheckerAutoRun.class.getSimpleName(); + } + + public String getName() { + return "在线监听器"; + } + + public void autoRun() { + HeartbeatUnifiedService heartbeatUnifiedService = SpringContextHolder.getBean(HeartbeatUnifiedServiceimpl.class); + + for(; !heartbeat_no_use; ThreadUtl.sleep((long)offline_loop_time_millions)) { + try { + heartbeatUnifiedService.offlineChecker(); + } catch (Exception var3) { + Date date = new Date(); + if (date.getTime() - this.recordTime.getTime() < (long)this.recordTimeOut) { + log.trace("离线事件异常发生时间因为小于{}毫秒,而被无视", this.recordTime); + return; + } + + this.recordTime = date; + log.warn("", var3); + } + } + + } +} diff --git a/acs/nladmin-system/src/main/java/org/nl/acs/heartbeat/dto/HeartbeatManageDto.java b/acs/nladmin-system/src/main/java/org/nl/acs/heartbeat/dto/HeartbeatManageDto.java index bd6e46a..10805fa 100644 --- a/acs/nladmin-system/src/main/java/org/nl/acs/heartbeat/dto/HeartbeatManageDto.java +++ b/acs/nladmin-system/src/main/java/org/nl/acs/heartbeat/dto/HeartbeatManageDto.java @@ -1,19 +1,45 @@ package org.nl.acs.heartbeat.dto; +import lombok.Data; import org.nl.acs.heartbeat.enums.HeartbeatType; import java.util.Date; - -public class HeartbeatManageDto extends Dto { +@Data +public class HeartbeatManageDto { private static final long serialVersionUID = 1L; + /** + * 资源号 + */ private String resource_code; + /** + * 资源名 + */ private String resource_name; + /** + * 状态 在线 离线 + */ private HeartbeatType status; private long duration; + /** + * 在线时间 + */ private Date online_datetime; + /** + * 离线时间 + */ private Date offline_datetime; + /** + * 上次接收时间 + */ private Date lastreceivetime; + private String id; + + private String is_active; + + private String create_by; + + private Date create_time; public HeartbeatManageDto() { } @@ -25,6 +51,14 @@ public class HeartbeatManageDto extends Dto { } + public String getId() { + return this.id; + } + + public String setId(String id) { + return this.id; + } + public String getResource_code() { return this.resource_code; } diff --git a/acs/nladmin-system/src/main/java/org/nl/acs/heartbeat/service_impl/HeartbeatManageServiceimpl.java b/acs/nladmin-system/src/main/java/org/nl/acs/heartbeat/service_impl/HeartbeatManageServiceimpl.java index 7557f97..7fd01e7 100644 --- a/acs/nladmin-system/src/main/java/org/nl/acs/heartbeat/service_impl/HeartbeatManageServiceimpl.java +++ b/acs/nladmin-system/src/main/java/org/nl/acs/heartbeat/service_impl/HeartbeatManageServiceimpl.java @@ -1,12 +1,15 @@ package org.nl.acs.heartbeat.service_impl; +import com.alibaba.fastjson.JSONArray; import org.nl.acs.heartbeat.domain.HeartbeatDomain; import org.nl.acs.heartbeat.dto.HeartbeatManageDto; import org.nl.acs.heartbeat.service.HeartbeatManageService; +import org.nl.modules.wql.core.bean.WQLObject; +import org.springframework.stereotype.Service; import java.util.List; import java.util.UUID; - +@Service public class HeartbeatManageServiceimpl implements HeartbeatManageService { public HeartbeatManageServiceimpl() { @@ -40,7 +43,10 @@ public class HeartbeatManageServiceimpl implements HeartbeatManageService { } public List queryAllActive() { - return null; + WQLObject wo = WQLObject.getWQLObject("acs_heartbeat"); + JSONArray arr = wo.query().getResultJSONArray(0); + List list = arr.toJavaList(HeartbeatManageDto.class); + return list; } public HeartbeatManageDto queryById(UUID id) { diff --git a/acs/nladmin-system/src/main/java/org/nl/acs/heartbeat/service_impl/HeartbeatUnifiedServiceimpl.java b/acs/nladmin-system/src/main/java/org/nl/acs/heartbeat/service_impl/HeartbeatUnifiedServiceimpl.java index 42ec13d..7d9e503 100644 --- a/acs/nladmin-system/src/main/java/org/nl/acs/heartbeat/service_impl/HeartbeatUnifiedServiceimpl.java +++ b/acs/nladmin-system/src/main/java/org/nl/acs/heartbeat/service_impl/HeartbeatUnifiedServiceimpl.java @@ -1,9 +1,11 @@ package org.nl.acs.heartbeat.service_impl; +import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import org.nl.acs.auto.initial.ApplicationAutoInitial; +import org.nl.acs.heartbeat.HeartbeatConfig; import org.nl.acs.heartbeat.HeartbeatEvent; import org.nl.acs.heartbeat.dto.HeartbeatManageDto; import org.nl.acs.heartbeat.enums.HeartbeatType; @@ -12,42 +14,47 @@ import org.nl.acs.heartbeat.service.HeartbeatManageService; import org.nl.acs.heartbeat.service.HeartbeatUnifiedService; import org.nl.modules.wql.util.SpringContextHolder; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationEventPublisher; +import org.springframework.stereotype.Service; import java.util.*; - +@Service public class HeartbeatUnifiedServiceimpl implements HeartbeatUnifiedService, ApplicationAutoInitial { + @Autowired + private ApplicationEventPublisher eventPublisher; + private List heartbeats = new ArrayList(); + @Autowired private HeartbeatManageService heartbeatManageService; - public HeartbeatUnifiedServiceimpl() { - } @Override public void autoInitial() throws Exception { - heartbeatManageService = SpringContextHolder.getBean("heartbeatManageServiceImpl"); - this.reload(); - Iterator iterator = this.heartbeats.iterator(); - - while (iterator.hasNext()) { - HeartbeatManageDto dto = (HeartbeatManageDto) iterator.next(); - if (dto.getOnline_datetime() == null) { - dto.setOnline_datetime(new Date()); - } - - if (dto.getLastreceivetime() == null) { - dto.setLastreceivetime(new Date()); - } - - dto.setOffline_datetime(new Date()); - dto.calculateDuration(); - dto.setStatus(HeartbeatType.offline); - this.heartbeatManageService.saveById(dto); - iterator.remove(); - } +// Iterator iterator = this.heartbeats.iterator(); +// +// while (iterator.hasNext()) { +// HeartbeatManageDto dto = (HeartbeatManageDto) iterator.next(); +// if (dto.getOnline_datetime() == null) { +// dto.setOnline_datetime(new Date()); +// } +// +// if (dto.getLastreceivetime() == null) { +// dto.setLastreceivetime(new Date()); +// } +// +// dto.setOffline_datetime(new Date()); +// dto.calculateDuration(); +// dto.setStatus(HeartbeatType.offline); +// dto.setId(IdUtil.simpleUUID()); +// dto.setIs_active("1"); +// dto.setCreate_by(dto.getResource_code()); +// this.heartbeatManageService.saveById(dto); +// iterator.remove(); +// } } @@ -68,7 +75,11 @@ public class HeartbeatUnifiedServiceimpl implements HeartbeatUnifiedService, App if (StrUtil.equals(dto.getResource_code(), heartbeatEvent.getResource_code())) { dto.setLastreceivetime(new Date()); dto.calculateDuration(); - isonline = true; + if(ObjectUtil.equals(dto.getStatus(),HeartbeatType.online)){ + isonline = true; + } else { + this.heartbeats.remove(dto); + } } } @@ -78,7 +89,13 @@ public class HeartbeatUnifiedServiceimpl implements HeartbeatUnifiedService, App heartbeatManageDto.setResource_name(heartbeatEvent.getResource_name()); heartbeatManageDto.setOnline_datetime(new Date()); heartbeatManageDto.setLastreceivetime(new Date()); + heartbeatManageDto.setCreate_time(new Date()); heartbeatManageDto.setStatus(HeartbeatType.online); + heartbeatManageDto.setId(IdUtil.simpleUUID()); + heartbeatManageDto.setIs_active("1"); + heartbeatManageDto.setCreate_by(heartbeatEvent.getResource_code()); +// this.heartbeatManageService.saveById(heartbeatManageDto); + this.heartbeats.add(heartbeatManageDto); // HeartbeatOnlineEvent heartbeatOnlineEvent = new HeartbeatOnlineEvent(); // heartbeatOnlineEvent.setHeartbeatManageDto(heartbeatManageDto); //ApplicationEventPublisher.trigger(heartbeatOnlineEvent); @@ -113,13 +130,19 @@ public class HeartbeatUnifiedServiceimpl implements HeartbeatUnifiedService, App long time = (new Date()).getTime() - last_time; if (time > (long) 500) { -// if (time > (long)HeartbeatConfig.max_alive_time_millions) { - dto.setOffline_datetime(new Date()); - dto.setStatus(HeartbeatType.offline); - HeartbeatOfflineEvent heartbeatOfflineEvent = new HeartbeatOfflineEvent(); - heartbeatOfflineEvent.setHeartbeatManageDto(dto); - //ApplicationEventPublisher.trigger(heartbeatOfflineEvent); - //log.trace("编号:{},名称:{}, 该资源已离线", dto.getResource_code(), dto.getResource_name()); + if (time > (long) HeartbeatConfig.max_alive_time_millions) { + if(!ObjectUtil.equal(dto.getStatus(),HeartbeatType.offline)){ + this.heartbeats.remove(dto); + dto.setOffline_datetime(new Date()); + dto.setStatus(HeartbeatType.offline); + this.heartbeats.add(dto); + } +// HeartbeatOfflineEvent heartbeatOfflineEvent = new HeartbeatOfflineEvent(); +// heartbeatOfflineEvent.setHeartbeatManageDto(dto); +// eventPublisher.publishEvent(heartbeatOfflineEvent); +// ApplicationEventPublisher.trigger(heartbeatOfflineEvent); + //log.trace("编号:{},名称:{}, 该资源已离线", dto.getResource_code(), dto.getResource_name()); + } } } diff --git a/acs/nladmin-system/src/main/java/org/nl/acs/opc/BlockedThreadPoolPolicy.java b/acs/nladmin-system/src/main/java/org/nl/acs/opc/BlockedThreadPoolPolicy.java new file mode 100644 index 0000000..feeb96b --- /dev/null +++ b/acs/nladmin-system/src/main/java/org/nl/acs/opc/BlockedThreadPoolPolicy.java @@ -0,0 +1,25 @@ +package org.nl.acs.opc; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.concurrent.RejectedExecutionHandler; +import java.util.concurrent.ThreadPoolExecutor; + +public class BlockedThreadPoolPolicy implements RejectedExecutionHandler { + private static final Logger log = LoggerFactory.getLogger(BlockedThreadPoolPolicy.class); + + public BlockedThreadPoolPolicy() { + } + + public void rejectedExecution(Runnable r, ThreadPoolExecutor e) { + if (!e.isShutdown()) { + try { + e.getQueue().put(r); + } catch (InterruptedException var4) { + log.debug("", var4); + } + } + + } +} diff --git a/acs/nladmin-system/src/main/java/org/nl/acs/opc/DeviceManageDto.java b/acs/nladmin-system/src/main/java/org/nl/acs/opc/DeviceManageDto.java index 1647976..bbcd560 100644 --- a/acs/nladmin-system/src/main/java/org/nl/acs/opc/DeviceManageDto.java +++ b/acs/nladmin-system/src/main/java/org/nl/acs/opc/DeviceManageDto.java @@ -43,7 +43,7 @@ public class DeviceManageDto { private String opc_server_code; private String opc_plc_id; private String opc_plc_code; - private Boolean is_configed; + private Boolean is_config; private Boolean is_exist; private Boolean is_entrance; /* 粉桶号 */ diff --git a/acs/nladmin-system/src/main/java/org/nl/acs/opc/IncreasedBlokdedThreadPoolPolicy.java b/acs/nladmin-system/src/main/java/org/nl/acs/opc/IncreasedBlokdedThreadPoolPolicy.java new file mode 100644 index 0000000..04aee5f --- /dev/null +++ b/acs/nladmin-system/src/main/java/org/nl/acs/opc/IncreasedBlokdedThreadPoolPolicy.java @@ -0,0 +1,22 @@ +package org.nl.acs.opc; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class IncreasedBlokdedThreadPoolPolicy implements IncreasedRejectedExecutionHandler { + private static final Logger log = LoggerFactory.getLogger(IncreasedBlokdedThreadPoolPolicy.class); + + public IncreasedBlokdedThreadPoolPolicy() { + } + + public void rejectedExecution(Runnable r, IncreasedThreadPoolExecutor e) { + if (!e.isShutdown()) { + try { + e.getQueue().put(r); + } catch (InterruptedException var4) { + log.debug("", var4); + } + } + + } +} diff --git a/acs/nladmin-system/src/main/java/org/nl/acs/opc/IncreasedRejectedExecutionHandler.java b/acs/nladmin-system/src/main/java/org/nl/acs/opc/IncreasedRejectedExecutionHandler.java new file mode 100644 index 0000000..0dcee2c --- /dev/null +++ b/acs/nladmin-system/src/main/java/org/nl/acs/opc/IncreasedRejectedExecutionHandler.java @@ -0,0 +1,5 @@ +package org.nl.acs.opc; + +public interface IncreasedRejectedExecutionHandler { + void rejectedExecution(Runnable var1, IncreasedThreadPoolExecutor var2); +} diff --git a/acs/nladmin-system/src/main/java/org/nl/acs/opc/IncreasedThreadPoolExecutor.java b/acs/nladmin-system/src/main/java/org/nl/acs/opc/IncreasedThreadPoolExecutor.java new file mode 100644 index 0000000..5124e98 --- /dev/null +++ b/acs/nladmin-system/src/main/java/org/nl/acs/opc/IncreasedThreadPoolExecutor.java @@ -0,0 +1,943 @@ +package org.nl.acs.opc; + +import java.util.*; +import java.util.concurrent.*; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.locks.AbstractQueuedSynchronizer; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; + +public class IncreasedThreadPoolExecutor extends AbstractExecutorService { + private final AtomicInteger ctl; + private static final int COUNT_BITS = 29; + private static final int CAPACITY = 536870911; + private static final int RUNNING = -536870912; + private static final int SHUTDOWN = 0; + private static final int STOP = 536870912; + private static final int TIDYING = 1073741824; + private static final int TERMINATED = 1610612736; + private final BlockingQueue workQueue; + private final ReentrantLock mainLock; + private final HashSet workers; + private final Condition termination; + private int largestPoolSize; + private long completedTaskCount; + private volatile ThreadFactory threadFactory; + private volatile IncreasedRejectedExecutionHandler handler; + private volatile long keepAliveTime; + private volatile boolean allowCoreThreadTimeOut; + private volatile int corePoolSize; + private volatile int maximumPoolSize; + private volatile int multiple; + private static final IncreasedRejectedExecutionHandler defaultHandler = new AbortPolicy(); + private static final RuntimePermission shutdownPerm = new RuntimePermission("modifyThread"); + private static final boolean ONLY_ONE = true; + + private static int runStateOf(int c) { + return c & -536870912; + } + + private static int workerCountOf(int c) { + return c & 536870911; + } + + private static int ctlOf(int rs, int wc) { + return rs | wc; + } + + private static boolean runStateLessThan(int c, int s) { + return c < s; + } + + private static boolean runStateAtLeast(int c, int s) { + return c >= s; + } + + private static boolean isRunning(int c) { + return c < 0; + } + + private boolean compareAndIncrementWorkerCount(int expect) { + return this.ctl.compareAndSet(expect, expect + 1); + } + + private boolean compareAndDecrementWorkerCount(int expect) { + return this.ctl.compareAndSet(expect, expect - 1); + } + + private void decrementWorkerCount() { + while(!this.compareAndDecrementWorkerCount(this.ctl.get())) { + } + + } + + private void advanceRunState(int targetState) { + int c; + do { + c = this.ctl.get(); + } while(!runStateAtLeast(c, targetState) && !this.ctl.compareAndSet(c, ctlOf(targetState, workerCountOf(c)))); + + } + + final void tryTerminate() { + while(true) { + int c = this.ctl.get(); + if (isRunning(c) || runStateAtLeast(c, 1073741824) || runStateOf(c) == 0 && !this.workQueue.isEmpty()) { + return; + } + + if (workerCountOf(c) != 0) { + this.interruptIdleWorkers(true); + return; + } + + ReentrantLock mainLock = this.mainLock; + mainLock.lock(); + + try { + if (!this.ctl.compareAndSet(c, ctlOf(1073741824, 0))) { + continue; + } + + try { + this.terminated(); + } finally { + this.ctl.set(ctlOf(1610612736, 0)); + this.termination.signalAll(); + } + } finally { + mainLock.unlock(); + } + + return; + } + } + + private void checkShutdownAccess() { + SecurityManager security = System.getSecurityManager(); + if (security != null) { + security.checkPermission(shutdownPerm); + ReentrantLock mainLock = this.mainLock; + mainLock.lock(); + + try { + Iterator var3 = this.workers.iterator(); + + while(var3.hasNext()) { + Worker w = (Worker)var3.next(); + security.checkAccess(w.thread); + } + } finally { + mainLock.unlock(); + } + } + + } + + private void interruptWorkers() { + ReentrantLock mainLock = this.mainLock; + mainLock.lock(); + + try { + Iterator var2 = this.workers.iterator(); + + while(var2.hasNext()) { + Worker w = (Worker)var2.next(); + w.interruptIfStarted(); + } + } finally { + mainLock.unlock(); + } + + } + + private void interruptIdleWorkers(boolean onlyOne) { + ReentrantLock mainLock = this.mainLock; + mainLock.lock(); + + try { + Iterator var3 = this.workers.iterator(); + + while(var3.hasNext()) { + Worker w = (Worker)var3.next(); + Thread t = w.thread; + if (!t.isInterrupted() && w.tryLock()) { + try { + t.interrupt(); + } catch (SecurityException var15) { + } finally { + w.unlock(); + } + } + + if (onlyOne) { + break; + } + } + } finally { + mainLock.unlock(); + } + + } + + private void interruptIdleWorkers() { + this.interruptIdleWorkers(false); + } + + final void reject(Runnable command) { + this.handler.rejectedExecution(command, this); + } + + void onShutdown() { + } + + final boolean isRunningOrShutdown(boolean shutdownOK) { + int rs = runStateOf(this.ctl.get()); + return rs == -536870912 || rs == 0 && shutdownOK; + } + + private List drainQueue() { + BlockingQueue q = this.workQueue; + ArrayList taskList = new ArrayList(); + q.drainTo(taskList); + if (!q.isEmpty()) { + Runnable[] var3 = (Runnable[])q.toArray(new Runnable[0]); + int var4 = var3.length; + + for(int var5 = 0; var5 < var4; ++var5) { + Runnable r = var3[var5]; + if (q.remove(r)) { + taskList.add(r); + } + } + } + + return taskList; + } + + private boolean addWorker(Runnable firstTask, boolean core) { + while(true) { + int c = this.ctl.get(); + int rs = runStateOf(c); + if (rs >= 0 && (rs != 0 || firstTask != null || this.workQueue.isEmpty())) { + return false; + } + + while(true) { + int wc = workerCountOf(c); + if (wc >= 536870911 || wc >= (core ? this.corePoolSize : this.maximumPoolSize)) { + return false; + } + + if (this.compareAndIncrementWorkerCount(c)) { + boolean workerStarted = false; + boolean workerAdded = false; + Worker w = null; + + try { + w = new Worker(firstTask); + Thread t = w.thread; + if (t != null) { + ReentrantLock mainLock = this.mainLock; + mainLock.lock(); + + try { + int rs1 = runStateOf(this.ctl.get()); + if (rs1 < 0 || rs1 == 0 && firstTask == null) { + if (t.isAlive()) { + throw new IllegalThreadStateException(); + } + + this.workers.add(w); + int s = this.workers.size(); + if (s > this.largestPoolSize) { + this.largestPoolSize = s; + } + + workerAdded = true; + } + } finally { + mainLock.unlock(); + } + + if (workerAdded) { + t.start(); + workerStarted = true; + } + } + } finally { + if (!workerStarted) { + this.addWorkerFailed(w); + } + + } + + return workerStarted; + } + + c = this.ctl.get(); + if (runStateOf(c) != rs) { + break; + } + } + } + } + + private void addWorkerFailed(Worker w) { + ReentrantLock mainLock = this.mainLock; + mainLock.lock(); + + try { + if (w != null) { + this.workers.remove(w); + } + + this.decrementWorkerCount(); + this.tryTerminate(); + } finally { + mainLock.unlock(); + } + + } + + private void processWorkerExit(Worker w, boolean completedAbruptly) { + if (completedAbruptly) { + this.decrementWorkerCount(); + } + + ReentrantLock mainLock = this.mainLock; + mainLock.lock(); + + try { + this.completedTaskCount += w.completedTasks; + this.workers.remove(w); + } finally { + mainLock.unlock(); + } + + this.tryTerminate(); + int c = this.ctl.get(); + if (runStateLessThan(c, 536870912)) { + if (!completedAbruptly) { + int min = this.allowCoreThreadTimeOut ? 0 : this.corePoolSize; + if (min == 0 && !this.workQueue.isEmpty()) { + min = 1; + } + + if (workerCountOf(c) >= min) { + return; + } + } + + this.addWorker((Runnable)null, false); + } + + } + + private Runnable getTask() { + boolean timedOut = false; + + while(true) { + int c = this.ctl.get(); + int rs = runStateOf(c); + if (rs >= 0 && (rs >= 536870912 || this.workQueue.isEmpty())) { + this.decrementWorkerCount(); + return null; + } + + int wc = workerCountOf(c); + boolean timed = this.allowCoreThreadTimeOut || wc > this.corePoolSize; + if (wc <= this.maximumPoolSize && (!timed || !timedOut) || wc <= 1 && !this.workQueue.isEmpty()) { + try { + Runnable r = timed ? (Runnable)this.workQueue.poll(this.keepAliveTime, TimeUnit.NANOSECONDS) : (Runnable)this.workQueue.take(); + if (r != null) { + return r; + } + + timedOut = true; + } catch (InterruptedException var7) { + timedOut = false; + } + } else if (this.compareAndDecrementWorkerCount(c)) { + return null; + } + } + } + + final void runWorker(Worker w) { + Thread wt = Thread.currentThread(); + Runnable task = w.firstTask; + w.firstTask = null; + w.unlock(); + boolean completedAbruptly = true; + + try { + while(task != null || (task = this.getTask()) != null) { + w.lock(); + if ((runStateAtLeast(this.ctl.get(), 536870912) || Thread.interrupted() && runStateAtLeast(this.ctl.get(), 536870912)) && !wt.isInterrupted()) { + wt.interrupt(); + } + + try { + this.beforeExecute(wt, task); + Throwable thrown = null; + + try { + task.run(); + } catch (RuntimeException var28) { + thrown = var28; + throw var28; + } catch (Error var29) { + thrown = var29; + throw var29; + } catch (Throwable var30) { + thrown = var30; + throw new Error(var30); + } finally { + this.afterExecute(task, (Throwable)thrown); + } + } finally { + task = null; + ++w.completedTasks; + w.unlock(); + } + } + + completedAbruptly = false; + } finally { + this.processWorkerExit(w, completedAbruptly); + } + + } + + public IncreasedThreadPoolExecutor(int corePoolSize, int maximumPoolSize, int multiple, long keepAliveTime, TimeUnit unit, BlockingQueue workQueue) { + this(corePoolSize, maximumPoolSize, multiple, keepAliveTime, unit, workQueue, Executors.defaultThreadFactory(), defaultHandler); + } + + public IncreasedThreadPoolExecutor(int corePoolSize, int maximumPoolSize, int multiple, long keepAliveTime, TimeUnit unit, BlockingQueue workQueue, ThreadFactory threadFactory) { + this(corePoolSize, maximumPoolSize, multiple, keepAliveTime, unit, workQueue, threadFactory, defaultHandler); + } + + public IncreasedThreadPoolExecutor(int corePoolSize, int maximumPoolSize, int multiple, long keepAliveTime, TimeUnit unit, BlockingQueue workQueue, IncreasedRejectedExecutionHandler handler) { + this(corePoolSize, maximumPoolSize, multiple, keepAliveTime, unit, workQueue, Executors.defaultThreadFactory(), handler); + } + + public IncreasedThreadPoolExecutor(int corePoolSize, int maximumPoolSize, int multiple, long keepAliveTime, TimeUnit unit, BlockingQueue workQueue, ThreadFactory threadFactory, IncreasedRejectedExecutionHandler handler) { + this.ctl = new AtomicInteger(ctlOf(-536870912, 0)); + this.mainLock = new ReentrantLock(); + this.workers = new HashSet(); + this.termination = this.mainLock.newCondition(); + if (corePoolSize >= 0 && maximumPoolSize > 0 && maximumPoolSize >= corePoolSize && keepAliveTime >= 0L) { + if (workQueue != null && threadFactory != null && handler != null) { + this.corePoolSize = corePoolSize; + this.maximumPoolSize = maximumPoolSize; + this.workQueue = workQueue; + this.keepAliveTime = unit.toNanos(keepAliveTime); + this.threadFactory = threadFactory; + this.handler = handler; + this.multiple = multiple; + } else { + throw new NullPointerException(); + } + } else { + throw new IllegalArgumentException(); + } + } + + public void execute(Runnable command) { + if (command == null) { + throw new NullPointerException(); + } else { + int c = this.ctl.get(); + if (workerCountOf(c) < this.corePoolSize) { + if (this.addWorker(command, true)) { + return; + } + + c = this.ctl.get(); + } + + if (isRunning(c) && this.workQueue.size() < workerCountOf(c) * this.multiple && this.workQueue.offer(command)) { + int recheck = this.ctl.get(); + if (!isRunning(recheck) && this.remove(command)) { + this.reject(command); + } else if (workerCountOf(recheck) == 0) { + this.addWorker((Runnable)null, false); + } + } else if (!this.addWorker(command, false)) { + this.reject(command); + } + + } + } + + public void shutdown() { + ReentrantLock mainLock = this.mainLock; + mainLock.lock(); + + try { + this.checkShutdownAccess(); + this.advanceRunState(0); + this.interruptIdleWorkers(); + this.onShutdown(); + } finally { + mainLock.unlock(); + } + + this.tryTerminate(); + } + + public List shutdownNow() { + ReentrantLock mainLock = this.mainLock; + mainLock.lock(); + + List tasks; + try { + this.checkShutdownAccess(); + this.advanceRunState(536870912); + this.interruptWorkers(); + tasks = this.drainQueue(); + } finally { + mainLock.unlock(); + } + + this.tryTerminate(); + return tasks; + } + + public boolean isShutdown() { + return !isRunning(this.ctl.get()); + } + + public boolean isTerminating() { + int c = this.ctl.get(); + return !isRunning(c) && runStateLessThan(c, 1610612736); + } + + public boolean isTerminated() { + return runStateAtLeast(this.ctl.get(), 1610612736); + } + + public boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException { + long nanos = unit.toNanos(timeout); + ReentrantLock mainLock = this.mainLock; + mainLock.lock(); + + boolean var7; + try { + while(!runStateAtLeast(this.ctl.get(), 1610612736)) { + if (nanos <= 0L) { + var7 = false; + return var7; + } + + nanos = this.termination.awaitNanos(nanos); + } + + var7 = true; + } finally { + mainLock.unlock(); + } + + return var7; + } + + protected void finalize() { + this.shutdown(); + } + + public void setThreadFactory(ThreadFactory threadFactory) { + if (threadFactory == null) { + throw new NullPointerException(); + } else { + this.threadFactory = threadFactory; + } + } + + public ThreadFactory getThreadFactory() { + return this.threadFactory; + } + + public void setRejectedExecutionHandler(IncreasedRejectedExecutionHandler handler) { + if (handler == null) { + throw new NullPointerException(); + } else { + this.handler = handler; + } + } + + public IncreasedRejectedExecutionHandler getRejectedExecutionHandler() { + return this.handler; + } + + public void setCorePoolSize(int corePoolSize) { + if (corePoolSize < 0) { + throw new IllegalArgumentException(); + } else { + int delta = corePoolSize - this.corePoolSize; + this.corePoolSize = corePoolSize; + if (workerCountOf(this.ctl.get()) > corePoolSize) { + this.interruptIdleWorkers(); + } else if (delta > 0) { + int k = Math.min(delta, this.workQueue.size()); + + while(k-- > 0 && this.addWorker((Runnable)null, true) && !this.workQueue.isEmpty()) { + } + } + + } + } + + public int getCorePoolSize() { + return this.corePoolSize; + } + + public boolean prestartCoreThread() { + return workerCountOf(this.ctl.get()) < this.corePoolSize && this.addWorker((Runnable)null, true); + } + + void ensurePrestart() { + int wc = workerCountOf(this.ctl.get()); + if (wc < this.corePoolSize) { + this.addWorker((Runnable)null, true); + } else if (wc == 0) { + this.addWorker((Runnable)null, false); + } + + } + + public int prestartAllCoreThreads() { + int n; + for(n = 0; this.addWorker((Runnable)null, true); ++n) { + } + + return n; + } + + public boolean allowsCoreThreadTimeOut() { + return this.allowCoreThreadTimeOut; + } + + public void allowCoreThreadTimeOut(boolean value) { + if (value && this.keepAliveTime <= 0L) { + throw new IllegalArgumentException("Core threads must have nonzero keep alive times"); + } else { + if (value != this.allowCoreThreadTimeOut) { + this.allowCoreThreadTimeOut = value; + if (value) { + this.interruptIdleWorkers(); + } + } + + } + } + + public void setMaximumPoolSize(int maximumPoolSize) { + if (maximumPoolSize > 0 && maximumPoolSize >= this.corePoolSize) { + this.maximumPoolSize = maximumPoolSize; + if (workerCountOf(this.ctl.get()) > maximumPoolSize) { + this.interruptIdleWorkers(); + } + + } else { + throw new IllegalArgumentException(); + } + } + + public int getMaximumPoolSize() { + return this.maximumPoolSize; + } + + public void setKeepAliveTime(long time, TimeUnit unit) { + if (time < 0L) { + throw new IllegalArgumentException(); + } else if (time == 0L && this.allowsCoreThreadTimeOut()) { + throw new IllegalArgumentException("Core threads must have nonzero keep alive times"); + } else { + long keepAliveTime = unit.toNanos(time); + long delta = keepAliveTime - this.keepAliveTime; + this.keepAliveTime = keepAliveTime; + if (delta < 0L) { + this.interruptIdleWorkers(); + } + + } + } + + public long getKeepAliveTime(TimeUnit unit) { + return unit.convert(this.keepAliveTime, TimeUnit.NANOSECONDS); + } + + public BlockingQueue getQueue() { + return this.workQueue; + } + + public boolean remove(Runnable task) { + boolean removed = this.workQueue.remove(task); + this.tryTerminate(); + return removed; + } + + public void purge() { + BlockingQueue q = this.workQueue; + + try { + Iterator it = q.iterator(); + + while(it.hasNext()) { + Runnable r = (Runnable)it.next(); + if (r instanceof Future && ((Future)r).isCancelled()) { + it.remove(); + } + } + } catch (ConcurrentModificationException var7) { + Object[] var3 = q.toArray(); + int var4 = var3.length; + + for(int var5 = 0; var5 < var4; ++var5) { + Object r = var3[var5]; + if (r instanceof Future && ((Future)r).isCancelled()) { + q.remove(r); + } + } + } + + this.tryTerminate(); + } + + public int getPoolSize() { + ReentrantLock mainLock = this.mainLock; + mainLock.lock(); + + int var2; + try { + var2 = runStateAtLeast(this.ctl.get(), 1073741824) ? 0 : this.workers.size(); + } finally { + mainLock.unlock(); + } + + return var2; + } + + public int getActiveCount() { + ReentrantLock mainLock = this.mainLock; + mainLock.lock(); + + try { + int n = 0; + Iterator var3 = this.workers.iterator(); + + while(var3.hasNext()) { + Worker w = (Worker)var3.next(); + if (w.isLocked()) { + ++n; + } + } + + int var8 = n; + return var8; + } finally { + mainLock.unlock(); + } + } + + public int getLargestPoolSize() { + ReentrantLock mainLock = this.mainLock; + mainLock.lock(); + + int var2; + try { + var2 = this.largestPoolSize; + } finally { + mainLock.unlock(); + } + + return var2; + } + + public long getTaskCount() { + ReentrantLock mainLock = this.mainLock; + mainLock.lock(); + + try { + long n = this.completedTaskCount; + Iterator var4 = this.workers.iterator(); + + while(var4.hasNext()) { + Worker w = (Worker)var4.next(); + n += w.completedTasks; + if (w.isLocked()) { + ++n; + } + } + + long var9 = n + (long)this.workQueue.size(); + return var9; + } finally { + mainLock.unlock(); + } + } + + public long getCompletedTaskCount() { + ReentrantLock mainLock = this.mainLock; + mainLock.lock(); + + try { + long n = this.completedTaskCount; + + Worker w; + for(Iterator var4 = this.workers.iterator(); var4.hasNext(); n += w.completedTasks) { + w = (Worker)var4.next(); + } + + long var9 = n; + return var9; + } finally { + mainLock.unlock(); + } + } + + public String toString() { + ReentrantLock mainLock = this.mainLock; + mainLock.lock(); + + long ncompleted; + int nworkers; + int nactive; + try { + ncompleted = this.completedTaskCount; + nactive = 0; + nworkers = this.workers.size(); + Iterator var6 = this.workers.iterator(); + + while(var6.hasNext()) { + Worker w = (Worker)var6.next(); + ncompleted += w.completedTasks; + if (w.isLocked()) { + ++nactive; + } + } + } finally { + mainLock.unlock(); + } + + int c = this.ctl.get(); + String rs = runStateLessThan(c, 0) ? "Running" : (runStateAtLeast(c, 1610612736) ? "Terminated" : "Shutting down"); + return super.toString() + "[" + rs + ", pool size = " + nworkers + ", active threads = " + nactive + ", queued tasks = " + this.workQueue.size() + ", completed tasks = " + ncompleted + "]"; + } + + protected void beforeExecute(Thread t, Runnable r) { + } + + protected void afterExecute(Runnable r, Throwable t) { + } + + protected void terminated() { + } + + public static class DiscardOldestPolicy implements IncreasedRejectedExecutionHandler { + public DiscardOldestPolicy() { + } + + public void rejectedExecution(Runnable r, IncreasedThreadPoolExecutor e) { + if (!e.isShutdown()) { + e.getQueue().poll(); + e.execute(r); + } + + } + } + + public static class DiscardPolicy implements IncreasedRejectedExecutionHandler { + public DiscardPolicy() { + } + + public void rejectedExecution(Runnable r, IncreasedThreadPoolExecutor e) { + } + } + + public static class AbortPolicy implements IncreasedRejectedExecutionHandler { + public AbortPolicy() { + } + + public void rejectedExecution(Runnable r, IncreasedThreadPoolExecutor e) { + throw new RejectedExecutionException("Task " + r.toString() + " rejected from " + e.toString()); + } + } + + public static class CallerRunsPolicy implements IncreasedRejectedExecutionHandler { + public CallerRunsPolicy() { + } + + public void rejectedExecution(Runnable r, IncreasedThreadPoolExecutor e) { + if (!e.isShutdown()) { + r.run(); + } + + } + } + + private final class Worker extends AbstractQueuedSynchronizer implements Runnable { + private static final long serialVersionUID = 6138294804551838833L; + final Thread thread; + Runnable firstTask; + volatile long completedTasks; + + Worker(Runnable firstTask) { + this.setState(-1); + this.firstTask = firstTask; + this.thread = IncreasedThreadPoolExecutor.this.getThreadFactory().newThread(this); + } + + public void run() { + IncreasedThreadPoolExecutor.this.runWorker(this); + } + + protected boolean isHeldExclusively() { + return this.getState() != 0; + } + + protected boolean tryAcquire(int unused) { + if (this.compareAndSetState(0, 1)) { + this.setExclusiveOwnerThread(Thread.currentThread()); + return true; + } else { + return false; + } + } + + protected boolean tryRelease(int unused) { + this.setExclusiveOwnerThread((Thread)null); + this.setState(0); + return true; + } + + public void lock() { + this.acquire(1); + } + + public boolean tryLock() { + return this.tryAcquire(1); + } + + public void unlock() { + this.release(1); + } + + public boolean isLocked() { + return this.isHeldExclusively(); + } + + void interruptIfStarted() { + Thread t; + if (this.getState() >= 0 && (t = this.thread) != null && !t.isInterrupted()) { + try { + t.interrupt(); + } catch (SecurityException var3) { + } + } + + } + } +} + diff --git a/acs/nladmin-system/src/main/java/org/nl/acs/opc/ThreadPoolUtl.java b/acs/nladmin-system/src/main/java/org/nl/acs/opc/ThreadPoolUtl.java new file mode 100644 index 0000000..b6d7f08 --- /dev/null +++ b/acs/nladmin-system/src/main/java/org/nl/acs/opc/ThreadPoolUtl.java @@ -0,0 +1,71 @@ +package org.nl.acs.opc; + +import java.util.concurrent.*; + +public class ThreadPoolUtl { + private static ExecutorService eventExecutorService = null; + private static ExecutorService cycleExecutorService = null; + + private ThreadPoolUtl() { + } + + public static ExecutorService getEventSingleInstanse() { + if (eventExecutorService == null) { + Class var0 = ThreadPoolUtl.class; + synchronized(ThreadPoolUtl.class) { + if (eventExecutorService == null) { + eventExecutorService = newIncreasedBlockedThreadPool(50, 200, 5); + } + } + } + + return eventExecutorService; + } + + public static ExecutorService getCycleSingleInstanse() { + if (cycleExecutorService == null) { + Class var0 = ThreadPoolUtl.class; + synchronized(ThreadPoolUtl.class) { + if (cycleExecutorService == null) { + cycleExecutorService = newIncreasedBlockedThreadPool(5, 200, 5); + } + } + } + + return cycleExecutorService; + } + + public static ExecutorService newIncreasedThreadPool() { + return newIncreasedThreadPool(50, 200, 5); + } + + public static ExecutorService newIncreasedBlockedThreadPool() { + return newIncreasedBlockedThreadPool(50, 200, 5); + } + + public static ExecutorService newIncreasedThreadPool(int corePoolSize, int maximumPoolSize, int multiple) { + return new IncreasedThreadPoolExecutor(corePoolSize, maximumPoolSize, multiple, 1L, TimeUnit.HOURS, new LinkedBlockingDeque(), new IncreasedBlokdedThreadPoolPolicy()); + } + + public static ExecutorService newIncreasedBlockedThreadPool(int corePoolSize, int maximumPoolSize, int multiple) { + int queueLength = maximumPoolSize * multiple; + return new IncreasedThreadPoolExecutor(corePoolSize, maximumPoolSize, multiple, 1L, TimeUnit.HOURS, new ArrayBlockingQueue(queueLength), new IncreasedBlokdedThreadPoolPolicy()); + } + + public static ExecutorService newBlockedThreadPool() { + return newBlockedThreadPool(50, 300, 200); + } + + public static ExecutorService newBlockedThreadPool(int coreNum, int maxNum, int cacheNum) { + return new ThreadPoolExecutor(coreNum, maxNum, 1L, TimeUnit.HOURS, new ArrayBlockingQueue(cacheNum), new BlockedThreadPoolPolicy()); + } + + public static ExecutorService newCachedThreadPool() { + return Executors.newCachedThreadPool(); + } + + public static ExecutorService newFixedThreadPool(int maxNum) { + return Executors.newFixedThreadPool(maxNum); + } + +}