问题:
有三个流程,流程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");
}
}
代码说明
- Process 类:
-
表示一个流程,包含流程名称、开始时间和结束时间。
-
提供 start()、end() 和 getDuration() 方法,分别用于启动流程、结束流程和计算流程时长。
- MainProcess 类:
-
继承 Process 类,表示主流程1。
-
包含子流程2和子流程3的实例。
-
重写 getDuration() 方法,计算主流程1的时长时排除子流程2和3的时间。
-
新增 calculateSubProcessDuration() 方法,动态计算子流程2和3的总时间(考虑包含、交集或无交集的情况)。
- 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); // 交集时长
- sub2Start.getTime() 和 sub3Start.getTime()
-
作用:获取子流程2和子流程3的开始时间(以毫秒为单位)。
-
说明:
-
sub2Start 是子流程2的开始时间(Date 类型)。
-
getTime() 方法将 Date 对象转换为从1970年1月1日00:00:00 GMT开始的毫秒数(long 类型)。
-
- Math.max(sub2Start.getTime(), sub3Start.getTime())
-
作用:计算两个开始时间中的较晚时间。
-
说明:
-
如果子流程2的开始时间晚于子流程3的开始时间,则返回子流程2的开始时间。
-
如果子流程3的开始时间晚于子流程2的开始时间,则返回子流程3的开始时间。
-
这个值表示两个流程的交集时间段的开始时间。
-
- sub2End.getTime() 和 sub3End.getTime()
-
作用:获取子流程2和子流程3的结束时间(以毫秒为单位)。
-
说明:
-
sub2End 是子流程2的结束时间(Date 类型)。
-
getTime() 方法将 Date 对象转换为从1970年1月1日00:00:00 GMT开始的毫秒数(long 类型)。
-
- Math.min(sub2End.getTime(), sub3End.getTime())
-
作用:计算两个结束时间中的较早时间。
-
说明:
-
如果子流程2的结束时间早于子流程3的结束时间,则返回子流程2的结束时间。
-
如果子流程3的结束时间早于子流程2的结束时间,则返回子流程3的结束时间。
-
这个值表示两个流程的交集时间段的结束时间。
-
- overlapEnd - overlapStart
-
作用:计算交集时间段的时长(以毫秒为单位)。
-
说明:
-
如果 overlapEnd 大于 overlapStart,则结果为正值,表示两个流程有交集。
-
如果 overlapEnd 小于或等于 overlapStart,则结果为负值或零,表示两个流程无交集。
-
- Math.max(0, overlapEnd - overlapStart)
-
作用:确保交集时长为非负数。
-
说明:
-
如果 overlapEnd - overlapStart 为负值(即两个流程无交集),则返回 0。
-
如果 overlapEnd - overlapStart 为正值(即两个流程有交集),则返回实际交集时长。
-