Java中用数组模拟三级MLFQ调度:queue[0](时间片2)、queue[1](时间片4)、queue[2](FCFS,时间片8),任务按剩余时间、队列层级和等待时间动态升降级,通过循环模拟CPU时间推进与上下文切换。

在 Java 中用数组实现多级反馈队列(MLFQ)调度算法,核心是模拟操作系统中多个优先级队列 + 时间片递减 + 任务动态降级的逻辑。不需要线程或真实进程控制,仅用数组+状态模拟即可清晰展现调度思想。
设计三级队列结构与数组表示
用三个一维数组(或 ArrayList)分别代表高、中、低三优先级就绪队列:
– queue[0]:最高优先级,时间片 = 2 单位,新任务/升权任务进入此队列
– queue[1]:中优先级,时间片 = 4 单位,超时未完成则降入此队列
– queue[2]:最低优先级,时间片 = 8 单位,采用 FCFS(先来先服务),不主动降级
每个任务可用一个简单类封装:
class Task {int id;
int remainingTime; // 剩余需执行时间
int queueLevel; // 当前所在队列层级(0/1/2)
int timeInQueue; // 在当前队列已等待时间(用于判断是否该升级)
}
模拟调度主循环逻辑
用一个 while 循环模拟 CPU 时间推进,每次步进 1 单位时间(或按时间片粒度跳转):
- 优先遍历 queue[0]:若非空,取首任务执行 1 单位时间(或执行满时间片 2),remainingTime 减 1;若执行完,移出;若时间片用尽但未完成,放入 queue[1] 尾部
- queue[0] 空时检查 queue[1]:同理执行(时间片=4),超时未完成则降入 queue[2]
- queue[0] 和 queue[1] 均空时,执行 queue[2] 首任务(无时间片限制,但为简化可设单次最多执行 1 单位,体现“准FCFS”)
- 每轮开始前,可加入简单“升权”规则:例如某任务在低队列等待 ≥10 时间单位,且期间无更高优先级任务到达,可将其移回 queue[1](需额外记录等待起始时间)
任务到达与队列管理细节
模拟任务动态到达(如按输入或预设数组):
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
立即学习“Java免费学习笔记(深入)”;
- 所有新任务初始进入 queue[0] 头部或尾部(推荐尾部,保持公平)
- 用 int[] arrivalTimes 存储各任务到达时刻,配合全局 clock 变量判断何时加入
- 数组操作建议用 ArrayList
替代原始数组:避免手动移动元素,add/remove 更直观;若坚持用数组,需维护每个 queue 的有效长度(如 size[0], size[1], size[2])并手动搬移 - 注意:MLFQ 不保证实时性,但要避免饥饿——可在 queue[2] 执行若干轮后,将其中等待最久的任务临时提升至 queue[1](即“老化”机制)
输出与验证调度行为
每单位时间或每次上下文切换时打印关键信息,便于验证逻辑正确性:
- 当前 clock 值
- 正在执行的任务 id 和剩余时间
- 各队列当前任务 id 列表(如 queue0: [T1,T3], queue1: [T2], queue2: [])
- 任务完成时记录周转时间(clock - arrivalTime)和响应时间(首次执行时刻 - arrivalTime)
跑几个典型用例:如 T1(到达0,总耗时1)、T2(到达1,总耗时10)、T3(到达2,总耗时3),观察是否 T1 快速完成、T2 先抢高优再逐步降级、T3 插入后短暂抢占——就能验证 MLFQ 的交互式友好特性。

















