Commit 4d0bfa78 authored by Tong Li's avatar Tong Li

多线程优化

parent e90e9ad9
......@@ -109,7 +109,7 @@ public class Chromosome {
/// <summary>
/// 解码后的调度结果
/// </summary>
private List<GAScheduleResult> Result;
private CopyOnWriteArrayList<GAScheduleResult> Result;
/// <summary>
/// 解码后的调度结果
......
......@@ -20,6 +20,7 @@ import java.time.Duration;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.stream.Collectors;
import java.util.concurrent.locks.ReentrantLock;
......@@ -436,7 +437,7 @@ if(finishedOrder==null||finishedOrder.size()==0)
List<ScheduleResultDetail> geneDetails = machineCalculator.getNextAvailableTime(machine, earliestStartTime, -1,
CopyOnWriteArrayList<ScheduleResultDetail> geneDetails = machineCalculator.getNextAvailableTime(machine, earliestStartTime, -1,
processingTimeTotal, chromosome.getResult(), operation.IsInterrupt!=1, true,processingTime, operation.getQuantity(), true);
......
......@@ -40,9 +40,9 @@ public class MachineCalculator {
/**
* 获取机器下一个可用时间窗口(考虑班次约束)
*/
public List<ScheduleResultDetail> getNextAvailableTime(Machine machine, int proposedStartTime,
public CopyOnWriteArrayList<ScheduleResultDetail> getNextAvailableTime(Machine machine, int proposedStartTime,
int prevtime, int processingTime,
List<GAScheduleResult> existingTasks,
CopyOnWriteArrayList<GAScheduleResult> existingTasks,
boolean isInterrupt, boolean istask,
double oneTime,double quantity,
boolean islockMachineTime) {
......@@ -62,16 +62,16 @@ public class MachineCalculator {
// 查找最早可用开始时间
private List<ScheduleResultDetail> findEarliestStart(
private CopyOnWriteArrayList<ScheduleResultDetail> findEarliestStart(
Machine machine, int processingTime, LocalDateTime currentTime,
String prevtime, List<GAScheduleResult> existingTasks,double oneTime,double quantity, boolean checkprevtime, boolean islockMachineTime
String prevtime, CopyOnWriteArrayList<GAScheduleResult> existingTasks,double oneTime,double quantity, boolean checkprevtime, boolean islockMachineTime
,boolean isInterrupt) {
List<GAScheduleResult> machineTasks =existingTasks.stream()
CopyOnWriteArrayList<GAScheduleResult> machineTasks =existingTasks.stream()
.filter(t -> t.getMachineId() == machine.getId())
.sorted(Comparator.comparingInt(GAScheduleResult::getStartTime))
.collect(Collectors.toList());
.collect(Collectors.toCollection(CopyOnWriteArrayList::new));
List<ScheduleResultDetail> times = new ArrayList<>();
CopyOnWriteArrayList<ScheduleResultDetail> times = new CopyOnWriteArrayList<>();
TimeSegment slot = GetCurrentOrNextShift(machine, currentTime, prevtime, checkprevtime);
if (slot == null) return times;
......@@ -173,17 +173,16 @@ public class MachineCalculator {
return times;
}
private List<ScheduleResultDetail> CaldEarliestStart(
private CopyOnWriteArrayList<ScheduleResultDetail> CaldEarliestStart(
Machine machine, int processingTime, LocalDateTime currentTime,
String prevtime, List<GAScheduleResult> machineTasks,double oneTime,double quantity, boolean checkprevtime, boolean islockMachineTime
String prevtime, CopyOnWriteArrayList<GAScheduleResult> machineTasks,double oneTime,double quantity, boolean checkprevtime, boolean islockMachineTime
,boolean isInterrupt) {
int remainingTime = processingTime;
LocalDateTime st = StringUtils.isEmpty(prevtime) ? currentTime : LocalDateTime.parse(prevtime);
LocalDateTime prevEnd = LocalDateTime.of(2000, 1, 1, 0, 0, 0);
List<ScheduleResultDetail> times = new ArrayList<>();
List<ScheduleResultDetail> oldTimes = new ArrayList<>();
CopyOnWriteArrayList<ScheduleResultDetail> times = new CopyOnWriteArrayList<>();
List<TimeSegment> timeSegments= findAvailableSegments(machine, currentTime, machineTasks, remainingTime, isInterrupt);
CopyOnWriteArrayList<TimeSegment> timeSegments= findAvailableSegments(machine, currentTime, machineTasks, remainingTime, isInterrupt);
int estimateIndex= (int) Math.ceil(remainingTime / (double) ONE_DAY_MINUTES);
List<TimeSegment> timeSegments1=null;
// if(estimateIndex>10)
......@@ -211,13 +210,13 @@ public class MachineCalculator {
return times;
}
private List<ScheduleResultDetail> CaldScheduleResultDetail(List<TimeSegment> timeSegments,Machine machine,LocalDateTime st,int remainingTime,double oneTime)
private List<ScheduleResultDetail> CaldScheduleResultDetail(CopyOnWriteArrayList<TimeSegment> timeSegments,Machine machine,LocalDateTime st,int remainingTime,double oneTime)
{
int processable1 =(int)calculateTotalAvailableSecond(timeSegments, st);
List<ScheduleResultDetail> times = new ArrayList<>();
List<ScheduleResultDetail> times = new CopyOnWriteArrayList<>();
TimeSegment shiftfrist= timeSegments.get(0);
......@@ -229,7 +228,7 @@ public class MachineCalculator {
// 计算有效时间
List<TimeSegment> timeSegments2= timeSegments.subList(1,timeSegments.size()-1);
CopyOnWriteArrayList<TimeSegment> timeSegments2= new CopyOnWriteArrayList<>(timeSegments.subList(1,timeSegments.size()-1));
LocalDateTime effectiveStart=timeSegments2.get(0).getStart();
LocalDateTime effectiveend=timeSegments2.get(timeSegments2.size()-1).getEnd();
......@@ -298,10 +297,10 @@ public class MachineCalculator {
* @param requireContinuous 是否不可中断(true=不可中断)
* @return 满足条件的可用片段列表
*/
private List<TimeSegment> findAvailableSegments(
private CopyOnWriteArrayList<TimeSegment> findAvailableSegments(
Machine machine,
LocalDateTime start,
List<GAScheduleResult> machineTasks,
CopyOnWriteArrayList<GAScheduleResult> machineTasks,
double requiredMinutes,
boolean requireContinuous) {
List<TimeSegment> availableSegments = new ArrayList<>();
......@@ -316,7 +315,7 @@ public class MachineCalculator {
// 替换while(true),增加明确退出条件(原逻辑保留,可根据业务补充退出判断)
while (true) {
// 统一过滤逻辑:消除重复的FindAll代码
List<TimeSegment> useSegments = filterValidUseSegments(machine.getAvailability(), current, requireContinuous, requiredMinutes);
CopyOnWriteArrayList<TimeSegment> useSegments = filterValidUseSegments(machine.getAvailability(), current, requireContinuous, requiredMinutes);
if (useSegments != null && !useSegments.isEmpty()) {
// 计算可用时间总和(保留原有逻辑)
......@@ -334,7 +333,7 @@ public class MachineCalculator {
{
days=0;
}
List<TimeSegment> newSegments = machineScheduler.generateTimeSegment(machine, lastSegmentEnd.plusDays(1),days);
CopyOnWriteArrayList<TimeSegment> newSegments = machineScheduler.generateTimeSegment(machine, lastSegmentEnd.plusDays(1),days);
addSegmentsWithDeduplication(machine, newSegments);
......@@ -350,7 +349,7 @@ public class MachineCalculator {
LocalDateTime firstSegmentStart = useSegments.get(0).getStart().compareTo(current) < 0?current:useSegments.get(0).getStart();
LocalDateTime lastSegmentEnd = useSegments.get(useSegments.size() - 1).getEnd();
//获取维修和当前任务
List<TimeSegment> conflictSegments = getConflictIntervals(machine, machineTasks, firstSegmentStart, lastSegmentEnd);
CopyOnWriteArrayList<TimeSegment> conflictSegments = getConflictIntervals(machine, machineTasks, firstSegmentStart, lastSegmentEnd);
if (conflictSegments == null || conflictSegments.isEmpty()) {
// 无冲突:直接返回可用片段(保留原有逻辑)
......@@ -361,7 +360,7 @@ public class MachineCalculator {
return useSegments;
} else {
// 有冲突:可选返回冲突前足够片段或跳过冲突
List<TimeSegment> resultSegments = handleConflictsWithSumLogic(useSegments, conflictSegments, current, requiredMinutes);
CopyOnWriteArrayList<TimeSegment> resultSegments = handleConflictsWithSumLogic(useSegments, conflictSegments, current, requiredMinutes);
if (resultSegments != null && !resultSegments.isEmpty()) {
if (resultSegments.get(0).getStart().compareTo(current) < 0) {
spiltMachineAvailable(machine, resultSegments.get(0), current);
......@@ -384,7 +383,7 @@ public class MachineCalculator {
.max(Comparator.comparing(TimeSegment::getEnd, (a, b) -> a.compareTo(b)))
.map(TimeSegment::getEnd)
.orElse(current);
List<TimeSegment> newSegments = machineScheduler.generateTimeSegment(machine, lastSegmentEnd.plusDays(1),0);
CopyOnWriteArrayList<TimeSegment> newSegments = machineScheduler.generateTimeSegment(machine, lastSegmentEnd.plusDays(1),0);
addSegmentsWithDeduplication(machine, newSegments);
}
}
......@@ -400,8 +399,8 @@ public class MachineCalculator {
* @return 刚好满足时长的片段数组
* @throws IllegalArgumentException 总时长不足时抛出
*/
public List<TimeSegment> getEnoughSegmentsByEstimateIndex(
List<TimeSegment> availableSegments,
public CopyOnWriteArrayList<TimeSegment> getEnoughSegmentsByEstimateIndex(
CopyOnWriteArrayList<TimeSegment> availableSegments,
LocalDateTime currentTime,
int requiredMinutes) {
// 基础校验
......@@ -470,37 +469,39 @@ public class MachineCalculator {
}
// ========== 步骤3:精准裁剪片段,返回最终结果 ==========
List<TimeSegment> resultList = availableSegments.subList(0,targetIndex);
CopyOnWriteArrayList<TimeSegment> resultList =new CopyOnWriteArrayList<>(availableSegments.subList(0,targetIndex)) ;
return resultList;
}
/**
* 计算从0到指定索引的所有时段的总有效分钟数
*/
private double calculateTotalMinutesByIndex(List<TimeSegment> segments, LocalDateTime currentTime, int endIndex) {
private double calculateTotalMinutesByIndex(CopyOnWriteArrayList<TimeSegment> segments, LocalDateTime currentTime, int endIndex) {
return calculateTotalAvailableSecond(segments.subList(0,endIndex), currentTime);
return calculateTotalAvailableSecond(new CopyOnWriteArrayList(segments.subList(0, endIndex)), currentTime);
}
/**
* 统一过滤有效可用片段
*/
private List<TimeSegment> filterValidUseSegments(List<TimeSegment> allSegments,
private CopyOnWriteArrayList<TimeSegment> filterValidUseSegments(CopyOnWriteArrayList<TimeSegment> allSegments,
LocalDateTime currentTime,
boolean requireContinuous,
double requiredMinutes) {
// 空判断
if (allSegments == null || allSegments.isEmpty()) {
return new ArrayList<>();
return new CopyOnWriteArrayList<>();
}
// 统一过滤条件
List<TimeSegment> baseValidSegments = allSegments.stream()
CopyOnWriteArrayList<TimeSegment> baseValidSegments = allSegments.stream()
.filter(slot -> !slot.isUsed() // 对应 !slot.IsUsed
&& slot.getType() != SegmentType.MAINTENANCE // 对应 slot.Type != SegmentType.Maintenance
&& slot.getEnd().compareTo(currentTime) > 0) // 对应 slot.End > currentTime
.collect(Collectors.toList());
.collect(Collectors.toCollection(CopyOnWriteArrayList::new));
// 无需不可中断或所需时长无效时,直接返回基础有效片段
if (!requireContinuous || requiredMinutes <= 0) {
......@@ -517,7 +518,7 @@ public class MachineCalculator {
* @param currentTime 当前时间
* @return 总可用时长(分钟)
*/
private double calculateTotalAvailableSecond(List<TimeSegment> useSegments, LocalDateTime currentTime) {
private double calculateTotalAvailableSecond(CopyOnWriteArrayList<TimeSegment> useSegments, LocalDateTime currentTime) {
// 空判断:
if (useSegments == null || useSegments.size()==0) {
return 0.0;
......@@ -539,13 +540,13 @@ public class MachineCalculator {
* 辅助方法:过滤出满足连续时长要求的片段(仅不可中断配置生效时调用)
* 前置剔除零散无效片段,减少后续逻辑处理量
*/
private List<TimeSegment> filterContinuousCompliantSegments(
List<TimeSegment> baseValidSegments,
private CopyOnWriteArrayList<TimeSegment> filterContinuousCompliantSegments(
CopyOnWriteArrayList<TimeSegment> baseValidSegments,
LocalDateTime currentTime,
double requiredContinuous) {
// 空判断
if (baseValidSegments == null || baseValidSegments.isEmpty()) {
return new ArrayList<>();
return new CopyOnWriteArrayList<>();
}
CopyOnWriteArrayList<TimeSegment> continuousCompliantSegments = new CopyOnWriteArrayList<>();
......@@ -605,22 +606,22 @@ public class MachineCalculator {
* 批量获取冲突区间(优化边界判断,更严谨)
* 依赖:Machine、ScheduleResult、TimeSegment、DateTime 类(已在前序代码中定义,需补充部分属性)
*/
private List<TimeSegment> getConflictIntervals(
private CopyOnWriteArrayList<TimeSegment> getConflictIntervals(
Machine machine,
List<GAScheduleResult> machineTasks,
CopyOnWriteArrayList<GAScheduleResult> machineTasks,
LocalDateTime start,
LocalDateTime end) {
List<TimeSegment> conflictIntervals = new ArrayList<>();
CopyOnWriteArrayList<TimeSegment> conflictIntervals = new CopyOnWriteArrayList<>();
// 1. 维护窗口冲突(优化重叠判断,更严谨)
if (machine.getMaintenanceWindows() != null && !machine.getMaintenanceWindows().isEmpty()) {
// 过滤重叠的维护窗口并转换为TimeSegment
List<TimeSegment> maintenanceConflicts = machine.getMaintenanceWindows().stream()
CopyOnWriteArrayList<TimeSegment> maintenanceConflicts = machine.getMaintenanceWindows().stream()
// 正确的重叠判断:w.StartTime < end && w.EndTime > start
.filter(w -> w.getStartTime().compareTo(end) < 0 && w.getEndTime().compareTo(start) > 0)
// 转换为TimeSegment对象
.map(w -> new TimeSegment(w.getStartTime(), w.getEndTime()))
.collect(Collectors.toList());
.collect(Collectors.toCollection(CopyOnWriteArrayList::new));
// 批量添加冲突片段
conflictIntervals.addAll(maintenanceConflicts);
}
......@@ -648,7 +649,7 @@ public class MachineCalculator {
// 按开始时间排序
return conflictIntervals.stream()
.sorted(Comparator.comparing(TimeSegment::getStart, Comparator.nullsLast(LocalDateTime::compareTo)))
.collect(Collectors.toList());
.collect(Collectors.toCollection(CopyOnWriteArrayList::new));
}
/**
* 按总和逻辑处理冲突(保留原有冲突处理逻辑,优化严谨性)
......@@ -658,9 +659,9 @@ public class MachineCalculator {
* @param requiredMinutes 所需总时长(分钟)
* @return 满足条件的片段列表,无满足条件时返回null
*/
private List<TimeSegment> handleConflictsWithSumLogic(
List<TimeSegment> useSegments,
List<TimeSegment> conflictSegments,
private CopyOnWriteArrayList<TimeSegment> handleConflictsWithSumLogic(
CopyOnWriteArrayList<TimeSegment> useSegments,
CopyOnWriteArrayList<TimeSegment> conflictSegments,
LocalDateTime currentTime,
double requiredMinutes) {
......@@ -668,12 +669,12 @@ public class MachineCalculator {
for (TimeSegment conflict : conflictSegments) {
LocalDateTime currentTime1=currentTime;
// 过滤冲突前的可用片段(
List<TimeSegment> preConflictSegments = useSegments.stream()
CopyOnWriteArrayList<TimeSegment> preConflictSegments = useSegments.stream()
.filter(slot ->
(slot.getStart().compareTo(currentTime1) >= 0 || slot.getEnd().compareTo(currentTime1) > 0)
&& slot.getEnd().compareTo(conflict.getStart()) <= 0
)
.collect(Collectors.toList());
.collect(Collectors.toCollection(CopyOnWriteArrayList::new));
// 计算冲突前片段的总可用时长
double preConflictTotalTime = calculateTotalAvailableSecond(preConflictSegments, currentTime);
......@@ -693,7 +694,7 @@ public class MachineCalculator {
/**
* 追加片段并去重、排序(避免冗余片段和遍历混乱)
*/
private void addSegmentsWithDeduplication(Machine machine, List<TimeSegment> newSegments) {
private void addSegmentsWithDeduplication(Machine machine, CopyOnWriteArrayList<TimeSegment> newSegments) {
// 空判断:新片段为null或空集合时直接返回,对应C#的 newSegments == null || newSegments.Count == 0
if (newSegments == null || newSegments.isEmpty()) {
return;
......
......@@ -12,6 +12,7 @@ import org.springframework.context.annotation.ScopeMetadata;
import javax.xml.transform.Result;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
......@@ -931,9 +932,9 @@ Integer newMachineId1=newMachineId.intValue();
chromosome.setResultOld(ProductionDeepCopyUtil.deepCopyList(chromosome.getResult(),GAScheduleResult.class));
chromosome.getResult().clear();
List<GAScheduleResult> Resultlock= chromosome.getResult().stream()
CopyOnWriteArrayList<GAScheduleResult> Resultlock= chromosome.getResult().stream()
.filter(o -> o.isIsLocked() == true)
.collect(Collectors.toList());
.collect(Collectors.toCollection(CopyOnWriteArrayList::new));
chromosome.setResult(ProductionDeepCopyUtil.deepCopyList(Resultlock,GAScheduleResult.class));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment