1、基于Timer实现定时执行的任务,并在满足条件下结束定时任务,为此实现抽象类TimerTaskJob类,并在UpgradeManager类中应用;
2、TreadJob类由TimerTaskJob替换,弃用TreadJob类。
2个文件已添加
1个文件已修改
287 ■■■■■ 已修改文件
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/util/TimerTaskJob.java 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/util/TimerTaskJobTest.java 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mw-rtu/src/main/java/com/dy/rtuMw/server/upgrade/UpgradeManager.java 177 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/util/TimerTaskJob.java
New file
@@ -0,0 +1,62 @@
package com.dy.common.util;
import java.util.Timer;
import java.util.TimerTask;
/**
 * @Author: liurunyu
 * @Date: 2024/11/20 17:49
 * @Description :
 * 此抽象类代替ThreadJob,原因:
 * 在while(true){}中使用Thread.sleep(),可能导致的严重性能问题,不推荐在循环中使用线程休眠。
 * Java线程实现采用内核线程实现,线程的休眠及唤醒(状态切换)需借助操作系统进行,这是一个极其耗时耗力的操作。
 * 在线程休眠或运行时间较长的情景下,其对性能的影响还不算明显,因为对线程状态的切换并不频繁。
 * 但若线程休眠及运行的时间都很短(例如毫秒/秒,文中案例就是一个典型案例),
 * 系统将频繁的对线程状态进行切换,导致严重的性能损耗,并对着循环次数的递增而放大。
 */
public abstract class TimerTaskJob {
    protected Timer timer;
    protected boolean stop = false ;
    public void stop(){
        this.stop = true ;
        if(this.timer != null){
            this.timer.cancel();
        }
    }
    public boolean isStop(){
        return this.stop ;
    }
    /**
     *
     * @param delay
     * @param interval
     * @param callback
     * @throws Exception
     */
    public void start(Long delay, Long interval, Callback callback) throws Exception {
        this.timer = new Timer();
        this.timer.schedule(new TimerTask() {
            public void run() {
                Exception exe = null ;
                Object obj = null ;
                try {
                    obj = execute() ;
                }catch(Exception e){
                    e.printStackTrace();
                    exe = e ;
                }finally {
                    if(callback != null){
                        if(exe != null){
                            callback.exception(exe);
                        }else{
                            callback.call(obj);
                        }
                    }
                }
            }
        }, delay , interval);
    }
    public abstract Object execute() throws Exception ;
}
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/util/TimerTaskJobTest.java
New file
@@ -0,0 +1,48 @@
package com.dy.common.util;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
/**
 * @Author: liurunyu
 * @Date: 2024/11/20 18:29
 * @Description
 */
public class TimerTaskJobTest extends TimerTaskJob implements Callback {
    private static int count = 0 ;
    public static void main(String[] args) throws Exception {
        TimerTaskJobTest obj = new TimerTaskJobTest() ;
        obj.start(1000L,  1000L, obj);
    }
    public Object execute() {
        count++ ;
        System.out.println("执行伺服线程" + count + "次");
        if(count == 10) {
            stop() ;
        }
        return true ;
    }
    ////////////////////////////////////////////////////
    //
    // 升级状态通知工作线程执行完成后回调的方法,
    // 也就是上面execute方法执行完成返回或抛出异常后,执行下面三个方法
    //
    ////////////////////////////////////////////////////
    @Override
    public void call(Object obj) {
        //线程工作执行一次,obj = Boolean(true)
        System.out.println("伺服线程执行一次回调");
    }
    @Override
    public void call(Object... objs) {
    }
    @Override
    public void exception(Exception e) {
        e.printStackTrace();
        System.out.println("伺服线程发生异常" + e.getMessage());
    }
}
pipIrr-platform/pipIrr-mw/pipIrr-mw-rtu/src/main/java/com/dy/rtuMw/server/upgrade/UpgradeManager.java
@@ -7,19 +7,19 @@
import com.dy.common.springUtil.SpringContextUtil;
import com.dy.common.util.Callback;
import com.dy.common.util.DateTime;
import com.dy.common.util.ThreadJob;
import com.dy.common.util.TimerTaskJob;
import com.dy.rtuMw.web.webRequest.WebRequestDeal;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.util.List;
/**
 * @Author: liurunyu
 * @Date: 2024/11/4 16:03
 *  升级管理类
 * @Author liurunyu
 * @Date 2024/11/4 16:03
 * @Description
 */
public class UpgradeManager extends ThreadJob implements Callback {
public class UpgradeManager extends TimerTaskJob implements Callback {
    private static final Logger log = LogManager.getLogger(UpgradeManager.class.getName());
@@ -29,8 +29,11 @@
    private Integer ugMaxRtuSameTime ;//同时升级RTU最大个数
    private UpgradeTask task ;//升级任务
    private boolean monitorFirst = true ;//是否是第一次监视
    private UpgradeManager(){}
    private UpgradeManager(){
        monitorFirst = true ;
    }
    public static UpgradeManager getInstance() {
        return UpgradeManager.INSTANCE;
@@ -47,7 +50,7 @@
    /**
     * 设置升级任务
     * @param vo UpgradeTaskVo 升级任务对象
     * @throws Exception
     * @throws Exception 异常
     */
    public void setUpgradeTask(UpgradeTaskVo vo) throws Exception {
        if(this.task != null && !this.task.taskIsOver){
@@ -68,7 +71,7 @@
                    this.task = null ;
                    throw ex ;
                }else{
                    this.start(this);
                    this.start(1000L, (long) UpgradeUnit.confVo.notifyStateInterval, this);
                }
            }
        }
@@ -79,9 +82,8 @@
     * 此功能可能不会开放出去,
     * 因为强制结束升级任务,对一个未升级完成的RTU就会卡死,
     * 所以当强制结束升级任务,代码逻辑并没有强制结果RTU升级过程,如果升级过程也强制停止,那么RTU真会卡死
     * @throws Exception
     */
    public void forceOverUpgradeTask() throws Exception {
    public void forceOverUpgradeTask() {
        if(this.task != null){
            this.stop();
            this.task.forceOver();
@@ -91,11 +93,11 @@
    /**
     * RTU有上行数据了,触发下发升级数据
     * @param rtuAddr
     * @param code
     * @param protocolName
     * @param protocolVersion
     * @param callbackCom
     * @param rtuAddr 控制器RTU地址
     * @param code 上行数据功能码
     * @param protocolName 上行数据对应的协议名称
     * @param protocolVersion 上行数据对应的协议版本号
     * @param callbackCom 回调函数,处理下行命令
     */
    public void trigger(String rtuAddr, String code, String protocolName, Short protocolVersion, Callback callbackCom){
        if(task != null && !task.taskIsOver){
@@ -110,7 +112,7 @@
    ////////////////////////////////////////////////////
    /**
     * 当前升级状态
     * @return
     * @return 当前升级状态
     */
    public UpgradeState currentUpgradeState() {
        if(task != null){
@@ -122,9 +124,10 @@
    /**
     * Rtu升级信息
     * @param rtuAddr
     * @return
     * @param rtuAddr 控制器RTU地址
     * @return 控制器RTU升级状态
     */
    @SuppressWarnings("unused")
    public UpgradeRtu upgradeRtuInfo(String rtuAddr){
        if(task != null){
            return task.upgradeInfos(rtuAddr) ;
@@ -135,9 +138,10 @@
    /**
     * Rtu升级信息
     * @param rtuAddrList
     * @return
     * @param rtuAddrList 控制器地址列表
     * @return 指定列表中的控制器RTU升级状态
     */
    @SuppressWarnings("unused")
    public List<UpgradeRtu> upgradeRtuInfos(List<String> rtuAddrList){
        if(task != null){
            return task.upgradeInfos(rtuAddrList) ;
@@ -148,8 +152,8 @@
    /**
     * Rtu升级信息
     * @return
     * 所有Rtu升级信息
     * @return 所有Rtu升级信息
     */
    public List<UpgradeRtu> upgradeRtuInfoAll(){
        if(task != null){
@@ -166,84 +170,64 @@
    // 统计状态 + 状态通知
    //
    ////////////////////////////////////////////////////
    @Override
    public Object execute() throws Exception {
        boolean first = true ;
        while (true){
            if(this.isStop()){
                break ;
            }
            if(first){
                try{
                    //首次启动,停1秒
                    Thread.sleep(1000L);
                }catch (Exception e){
                }
            }else{
                try{
                    //停X毫秒
                    Thread.sleep(UpgradeUnit.confVo.notifyStateInterval);
                }catch (Exception e){
                }
            }
            if(this.task == null
                    || this.task.taskVo == null
                    || this.task.taskVo.rtuAddrList == null
                    || this.task.taskVo.rtuAddrList.size() == 0){
                //任务为空
                break ;
            }else{
                if(!this.task.taskIsOver){
                    //升级任务未完成
                    //工作1:判断是否无任何一个RTU进行过升级,并且达到时限,则认为当前升级任务完成
                    //-1:无一RTU升级且超时,0:无RTU升级但未超时等待,1有RTU升级正常执行
                    int temp = this.task.countNoOneRtuUpgradeInDuration() ;
                    if(temp == -1){
                        this.task.taskIsOver = true ;
                        //任务已经完成
                        this.stop();
                    }else if(temp == 1){
                        //工作2:统计当前正在升级的RTU数量,为同时升级数量限制做准备
                        this.task.countRunningRtuCount() ;
                        //工作3:统计需要升级但当前离线RTU的情况,超过时限的设备为升级完成
                        this.task.countOffRtuAndSetIfOver() ;
                        //工作4:统计是否全部升级完成
                        this.task.taskIsOver = this.task.countIsAllOver() ;
                    }else if(temp == 0){
                        //不作为
                    }
                    if(this.task.taskIsOver){
                        if(!this.task.taskOverType.equals(UpgradeTask.TaskOverType_Force)){
                            //任务不是强制结束的
                            this.task.taskOverType = UpgradeTask.TaskOverType_Natural ;//任务完成方式(自然,强制)
                            this.task.taskOverDt = DateTime.yyyy_MM_dd_HH_mm_ss() ;//任务完成时间(yyyy-mm-dd HH:MM:SS)
                        }
                        //任务完成,执行最后一次升级状态通知
                        //工作5:升级状态通知
                        //if(!first){
                        //    this.notifyUpgradeStatus() ;
                        //}
                    }else{
                        //任务未完成,继续执行升级状态通知
                        //工作5: 升级状态通知
                        //if(!first){
                        //    this.notifyUpgradeStatus() ;
                        //}
                    }
                    //工作5:升级状态通知
                    if(!first){
                        this.notifyUpgradeStatus() ;
                    }
                }else{
    public Object execute() {
        if(this.task == null
                || this.task.taskVo == null
                || this.task.taskVo.rtuAddrList == null
                || this.task.taskVo.rtuAddrList.size() == 0){
            //任务为空
            this.stop() ;
        }else{
            if(!this.task.taskIsOver){
                //升级任务未完成
                //工作1:判断是否无任何一个RTU进行过升级,并且达到时限,则认为当前升级任务完成
                //-1:无一RTU升级且超时,0:无RTU升级但未超时等待,1有RTU升级正常执行
                int temp = this.task.countNoOneRtuUpgradeInDuration() ;
                if(temp == -1){
                    this.task.taskIsOver = true ;
                    //任务已经完成
                    this.stop();
                }else if(temp == 1){
                    //工作2:统计当前正在升级的RTU数量,为同时升级数量限制做准备
                    this.task.countRunningRtuCount() ;
                    //工作3:统计需要升级但当前离线RTU的情况,超过时限的设备为升级完成
                    this.task.countOffRtuAndSetIfOver() ;
                    //工作4:统计是否全部升级完成
                    this.task.taskIsOver = this.task.countIsAllOver() ;
                }else if(temp == 0){
                    //不作为
                }
                if(this.task.taskIsOver){
                    if(!this.task.taskOverType.equals(UpgradeTask.TaskOverType_Force)){
                        //任务不是强制结束的
                        this.task.taskOverType = UpgradeTask.TaskOverType_Natural ;//任务完成方式(自然,强制)
                        this.task.taskOverDt = DateTime.yyyy_MM_dd_HH_mm_ss() ;//任务完成时间(yyyy-mm-dd HH:MM:SS)
                    }
                    //任务完成,执行最后一次升级状态通知
                    //工作5:升级状态通知
                    //if(!first){
                    //    this.notifyUpgradeStatus() ;
                    //}
                }else{
                    //任务未完成,继续执行升级状态通知
                    //工作5: 升级状态通知
                    //if(!first){
                    //    this.notifyUpgradeStatus() ;
                    //}
                }
                //工作5:升级状态通知
                if(!this.monitorFirst){
                    this.notifyUpgradeStatus() ;
                }
            }else{
                //任务已经完成
                this.stop();
            }
            if(first){
                first = false ;
            }
        }
        if(this.monitorFirst){
            this.monitorFirst = false ;
        }
        return true ;
    }
@@ -271,7 +255,6 @@
    @Override
    public void call(Object obj) {
        //线程工作执行完了,obj = Boolean(true)
        this.thread = null ;//赋值为null,使线程对象被垃圾回收器回收
    }
    @Override
    public void call(Object... objs) {