You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

带时间片的抢占式SJF算法Java程序:输出不符预期求助

问题描述

需要实现**带时间片的抢占式最短作业优先(Pre-emptive SJF With TimeQuantum)**进程调度算法,核心规则如下:

  • 给定进程名、到达时间、Burst Time数组及时间片变量;
  • 仅允许对已到达的进程执行Burst Time递减操作;
  • 每次选择已到达且Burst Time最短的进程:
    1. 若只有一个最短进程,将其Burst Time减1;
    2. 若多个已到达进程Burst Time相等,为这些进程各减去时间片时长;
  • 重复操作直到所有进程Burst Time为0,每次执行时打印进程名及执行时长。

样例参考

  • 样例输入:("P1", 4, 5),("P2", 1, 6),("P3", 1, 6),("P4", 2, 4),("P5", 3, 3)
  • 预期输出:P2 execute 2 unit, P3 execute 2 unit, P5 execute 1 unit, P5 execute 1 unit, P5 execute 1 unit, P2 execute 2 unit, P3 execute 2 unit, P4 execute 2 unit, P2 execute 2 unit, P3 execute 2 unit, P4 execute 2 unit, P1 execute 1 unit, P1 execute 1 unit, P1 execute 1 unit, P1 execute 1 unit, P1 execute 1 unit.

现有Java代码无法输出预期结果,需排查逻辑问题并修正。


原代码核心问题
  1. 数据关联破坏:直接对arrivalTime数组排序,导致进程名、到达时间、Burst Time的对应关系完全混乱;
  2. 调度逻辑错误:使用普通队列无法实现“选择已到达且Burst Time最短”的核心逻辑,仅从队列取首个进程,未做最短作业筛选;
  3. 多进程场景未处理:未判断多个已到达进程Burst Time相同的情况,无法按规则分配时间片;
  4. 时间与Burst Time更新错误:时间推进和Burst Time修改逻辑不符合“每次减1或时间片”的要求,且未处理无已到达进程时的时间递增;
  5. 进程未重新调度:执行完时间片的进程未重新加入候选队列,导致后续无法继续调度。

修正后的代码
import java.util.*;

class Process {
    String name;
    int arrivalTime;
    int burstTime;
    int remainingTime;

    public Process(String name, int arrivalTime, int burstTime) {
        this.name = name;
        this.arrivalTime = arrivalTime;
        this.burstTime = burstTime;
        this.remainingTime = burstTime;
    }
}

public class PreemptiveSJFWithTimeQuantum {
    public static void main(String[] args) {
        // 样例输入(可替换为Scanner输入,此处为测试方便直接初始化)
        List<Process> processes = new ArrayList<>();
        processes.add(new Process("P1", 4, 5));
        processes.add(new Process("P2", 1, 6));
        processes.add(new Process("P3", 1, 6));
        processes.add(new Process("P4", 2, 4));
        processes.add(new Process("P5", 3, 3));
        int timeQuantum = 2; // 对应样例的时间片

        int currentTime = 0;
        List<String> outputRecords = new ArrayList<>();

        // 循环直到所有进程完成
        while (processes.stream().anyMatch(p -> p.remainingTime > 0)) {
            // 筛选当前已到达且未完成的进程
            List<Process> arrivedProcesses = processes.stream()
                    .filter(p -> p.arrivalTime <= currentTime && p.remainingTime > 0)
                    .toList();

            // 无已到达进程时,时间递增
            if (arrivedProcesses.isEmpty()) {
                currentTime++;
                continue;
            }

            // 找到已到达进程中的最小剩余Burst Time
            int minRemaining = arrivedProcesses.stream()
                    .mapToInt(Process::getRemainingTime)
                    .min()
                    .orElse(Integer.MAX_VALUE);

            // 筛选出所有剩余时间等于最小值的进程
            List<Process> shortestProcesses = arrivedProcesses.stream()
                    .filter(p -> p.remainingTime == minRemaining)
                    .toList();

            if (shortestProcesses.size() == 1) {
                // 单个最短进程:执行1单位时间
                Process target = shortestProcesses.get(0);
                target.remainingTime--;
                currentTime++;
                outputRecords.add(target.name + " execute 1 unit");
            } else {
                // 多个最短进程:每个执行时间片时长(不超过剩余时间)
                for (Process target : shortestProcesses) {
                    int executeDuration = Math.min(timeQuantum, target.remainingTime);
                    target.remainingTime -= executeDuration;
                    currentTime += executeDuration;
                    outputRecords.add(target.name + " execute " + executeDuration + " unit");
                }
            }
        }

        // 按预期格式输出结果
        System.out.println(String.join(", ", outputRecords) + ".");
    }
}

关键修正说明
  1. 封装进程实体:用Process类统一管理进程的所有属性,避免数组排序导致的数据错位;
  2. 精准筛选已到达进程:每次循环先过滤出当前时间点已到达且未完成的进程,符合规则要求;
  3. 实现最短作业选择:先确定已到达进程的最小剩余Burst Time,再筛选出所有符合该值的进程,满足核心调度逻辑;
  4. 分场景处理执行逻辑:
    • 单个最短进程:每次执行1单位时间,对应规则中Burst Time减1的要求;
    • 多个最短进程:每个进程执行时间片时长(不超过剩余时间),符合规则中多进程的处理方式;
  5. 正确推进时间:无已到达进程时递增时间,有进程执行时根据执行时长更新时间;
  6. 结果统一输出:用列表收集所有执行记录,最后按预期格式拼接输出。

内容的提问来源于stack exchange,提问作者Forlan Beckham

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 11:21:07