主流程发起,去除子流程的时长计算问题

问题:

有三个流程,流程1.2.3,流程2.3是流程1的子流程,若在流程1的过程中发起流程2.3,计算流程1的时长要排除流程2.3的时间,流程2.3之间可能是包含、交集、无交集三种。

实现

代码:

java 复制代码
import java.util.Date;

class Process {
    private String name;
    private Date startTime;
    private Date endTime;

    public Process(String name) {
        this.name = name;
    }

    // 开始流程
    public void start() {
        this.startTime = new Date();
        System.out.println(name + " started at: " + startTime);
    }

    // 结束流程
    public void end() {
        this.endTime = new Date();
        System.out.println(name + " ended at: " + endTime);
    }

    // 获取流程开始时间
    public Date getStartTime() {
        return startTime;
    }

    // 获取流程结束时间
    public Date getEndTime() {
        return endTime;
    }

    // 计算流程时长(毫秒)
    public long getDuration() {
        if (startTime == null || endTime == null) {
            throw new IllegalStateException("Process " + name + " has not started or ended.");
        }
        return endTime.getTime() - startTime.getTime();
    }
}

class MainProcess extends Process {
    private Process subProcess2;
    private Process subProcess3;

    public MainProcess(String name) {
        super(name);
        this.subProcess2 = new Process("Sub-Process 2");
        this.subProcess3 = new Process("Sub-Process 3");
    }

    // 启动子流程2
    public void startSubProcess2() {
        subProcess2.start();
    }

    // 结束子流程2
    public void endSubProcess2() {
        subProcess2.end();
    }

    // 启动子流程3
    public void startSubProcess3() {
        subProcess3.start();
    }

    // 结束子流程3
    public void endSubProcess3() {
        subProcess3.end();
    }

    // 计算主流程1的时长(排除子流程2和3的时间)
    @Override
    public long getDuration() {
        long mainDuration = super.getDuration(); // 主流程总时长

        // 计算子流程2和3的总时间(考虑包含、交集或无交集的情况)
        long subProcessDuration = calculateSubProcessDuration();

        return mainDuration - subProcessDuration; // 排除子流程时间
    }

    // 计算子流程2和3的总时间
    private long calculateSubProcessDuration() {
        Date sub2Start = subProcess2.getStartTime();
        Date sub2End = subProcess2.getEndTime();
        Date sub3Start = subProcess3.getStartTime();
        Date sub3End = subProcess3.getEndTime();

        // 如果子流程2或3未启动或未结束,返回0
        if (sub2Start == null || sub2End == null || sub3Start == null || sub3End == null) {
            return 0;
        }

        // 计算子流程2和3的时间交集
        long overlapStart = Math.max(sub2Start.getTime(), sub3Start.getTime());
        long overlapEnd = Math.min(sub2End.getTime(), sub3End.getTime());
        long overlapDuration = Math.max(0, overlapEnd - overlapStart); // 交集时长

        // 计算子流程2和3的总时长(去重交集部分)
        long sub2Duration = subProcess2.getDuration();
        long sub3Duration = subProcess3.getDuration();
        return sub2Duration + sub3Duration - overlapDuration;
    }
}

public class ProcessManagement {
    public static void main(String[] args) throws InterruptedException {
        MainProcess process1 = new MainProcess("Process 1");

        // 启动主流程1
        process1.start();
        Thread.sleep(1000); // 模拟主流程1的运行时间

        // 启动子流程2
        process1.startSubProcess2();
        Thread.sleep(2000); // 模拟子流程2的运行时间

        // 启动子流程3(与子流程2有交集)
        process1.startSubProcess3();
        Thread.sleep(1500); // 模拟子流程3的运行时间
        process1.endSubProcess3();

        // 结束子流程2
        process1.endSubProcess2();

        Thread.sleep(1000); // 模拟主流程1的剩余运行时间

        // 结束主流程1
        process1.end();

        // 计算并输出主流程1的时长(排除子流程2和3的时间)
        System.out.println("Process 1 duration (excluding sub-processes): " + process1.getDuration() + " ms");
    }
}

代码说明

  1. Process 类:
  • 表示一个流程,包含流程名称、开始时间和结束时间。

  • 提供 start()、end() 和 getDuration() 方法,分别用于启动流程、结束流程和计算流程时长。

  1. MainProcess 类:
  • 继承 Process 类,表示主流程1。

  • 包含子流程2和子流程3的实例。

  • 重写 getDuration() 方法,计算主流程1的时长时排除子流程2和3的时间。

  • 新增 calculateSubProcessDuration() 方法,动态计算子流程2和3的总时间(考虑包含、交集或无交集的情况)。

  1. ProcessManagement 类:
  • 模拟流程的执行过程,包括主流程1和子流程2、3的启动与结束。

  • 输出主流程1的时长(排除子流程2和3的时间)。

关键点

  • 时间交集计算:通过比较子流程2和3的开始和结束时间,计算它们的交集时长。

  • 去重逻辑:在计算子流程总时间时,减去交集部分,避免重复计算。

  • 动态适应:无论子流程2和3是包含、交集还是无交集,都能正确计算主流程1的时长。

关键代码解析

java 复制代码
long overlapStart = Math.max(sub2Start.getTime(), sub3Start.getTime());
long overlapEnd = Math.min(sub2End.getTime(), sub3End.getTime());
long overlapDuration = Math.max(0, overlapEnd - overlapStart); // 交集时长
  1. sub2Start.getTime() 和 sub3Start.getTime()
  • 作用:获取子流程2和子流程3的开始时间(以毫秒为单位)。

  • 说明:

    • sub2Start 是子流程2的开始时间(Date 类型)。

    • getTime() 方法将 Date 对象转换为从1970年1月1日00:00:00 GMT开始的毫秒数(long 类型)。

  1. Math.max(sub2Start.getTime(), sub3Start.getTime())
  • 作用:计算两个开始时间中的较晚时间。

  • 说明:

    • 如果子流程2的开始时间晚于子流程3的开始时间,则返回子流程2的开始时间。

    • 如果子流程3的开始时间晚于子流程2的开始时间,则返回子流程3的开始时间。

    • 这个值表示两个流程的交集时间段的开始时间。

  1. sub2End.getTime() 和 sub3End.getTime()
  • 作用:获取子流程2和子流程3的结束时间(以毫秒为单位)。

  • 说明:

    • sub2End 是子流程2的结束时间(Date 类型)。

    • getTime() 方法将 Date 对象转换为从1970年1月1日00:00:00 GMT开始的毫秒数(long 类型)。

  1. Math.min(sub2End.getTime(), sub3End.getTime())
  • 作用:计算两个结束时间中的较早时间。

  • 说明:

    • 如果子流程2的结束时间早于子流程3的结束时间,则返回子流程2的结束时间。

    • 如果子流程3的结束时间早于子流程2的结束时间,则返回子流程3的结束时间。

    • 这个值表示两个流程的交集时间段的结束时间。

  1. overlapEnd - overlapStart
  • 作用:计算交集时间段的时长(以毫秒为单位)。

  • 说明:

    • 如果 overlapEnd 大于 overlapStart,则结果为正值,表示两个流程有交集。

    • 如果 overlapEnd 小于或等于 overlapStart,则结果为负值或零,表示两个流程无交集。

  1. Math.max(0, overlapEnd - overlapStart)
  • 作用:确保交集时长为非负数。

  • 说明:

    • 如果 overlapEnd - overlapStart 为负值(即两个流程无交集),则返回 0。

    • 如果 overlapEnd - overlapStart 为正值(即两个流程有交集),则返回实际交集时长。

相关推荐
顾洋洋几秒前
WASM与OPFS组合技系列三(魔改写操作)
前端·javascript·webassembly
清粥油条可乐炸鸡7 分钟前
el-transfer穿梭框数据量过大的解决方案
前端·javascript
只因从未离去7 分钟前
黑马Java基础笔记-4
java·开发语言·笔记
天天扭码7 分钟前
Trae 04.22 版本:前端学习者的智能成长助手
前端·trae
kurer9 分钟前
Java通配符深入理解
java
会功夫的李白9 分钟前
PDF嵌入隐藏的文字
java·pdf·itext
snakeshe101010 分钟前
深入解析React Hooks:useCallback与useMemo的原理与区别
前端
听风吹等浪起11 分钟前
html5:从零构建经典游戏-扫雷游戏
前端·html·html5
独立开阀者_FwtCoder12 分钟前
TypeScript 是怎么工作的?一文带你深入编译器内部流程
前端·javascript·面试
一只码代码的章鱼15 分钟前
学习笔记2(Lombok+算法)
笔记·学习·算法