Répertoire d'articles
Premier entré, premier sorti
Planifiez les tâches directement en fonction du temps d'attente. Lorsque la tâche est chargée, la première à être chargée est la première à être planifiée.
Tâche la plus courte d'abord
Planifiez les tâches directement en fonction du temps de service. Lorsque plusieurs tâches se trouvent dans la file d'attente de chargement, la tâche avec le temps de service le plus court est planifiée en premier.
Rapport de réponse le plus élevé en premier
Planifiez les tâches en fonction du temps d'attente et du temps de service.
响应比:(等待时间 + 服务时间) / 服务时间
Lorsque plusieurs tâches sont dans la file d'attente de chargement, la réponse à la requête est planifiée avant la tâche la plus élevée.
Code
package job;
import java.math.BigDecimal;
import java.math.MathContext;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Scanner;
/**
* @author wenei
* @date 2020-11-30 8:37
*/
public class Test {
enum JobStatus {
/**
* 等待 wait
*/
W,
/**
* 就绪 ready
*/
R,
/**
* 完成 finish
*/
F
}
static class Job {
// 到达时间
Integer arrivalTime;
// 服务时间
Integer serviceTime;
// 开始时间
Integer startTime;
// 结束时间
Integer endTime;
// 周转时间
Integer cycleTime;
// 带权周转时间
BigDecimal weightedTurnaroundTime;
// 作业状态 默认为等待
JobStatus status = JobStatus.W;
// 等待时间 times - arrivalTime
// 要求服务时间 serviceTime
}
/**
* 任务链表
*/
private static LinkedList<Job> jobs = new LinkedList<>();
/**
* 就绪任务
*/
private static LinkedList<Job> readyJobs = new LinkedList<>();
/**
* 时间量
*/
private static int times = 0;
// 统计用数据 region start
/**任务个数*/
private static int count = 0;
/**总周转周期*/
private static BigDecimal cycleTimeSum = BigDecimal.ZERO;
/**总带权周转时间*/
private static BigDecimal weightedTurnaroundTimeSum = BigDecimal.ZERO;;
// region end
private static void addJob(int arrivalTime, int serviceTime) {
Job job = new Job();
job.arrivalTime = arrivalTime;
job.serviceTime = serviceTime;
jobs.addLast(job);
count++;
}
/**
* 运行作业
*/
private static void running(Job job) {
// 开始时间
job.startTime = times;
// 完成时间
job.endTime = job.startTime + job.serviceTime;
// 周转时间
job.cycleTime = job.endTime - job.arrivalTime;
// 带权周转时间
job.weightedTurnaroundTime = BigDecimal.valueOf(job.cycleTime)
.divide(BigDecimal.valueOf(job.serviceTime), MathContext.DECIMAL32);
job.status = JobStatus.F;
times += job.serviceTime;
// 加载当前times之前的任务到readyJobs中
load();
dips(job);
}
/**
* 打印信息
*/
private static void dips(Job job) {
System.out.println("当前时间: " + times);
System.out.println("到达时间:" + job.arrivalTime);
System.out.println("服务时间:" + job.serviceTime);
System.out.println("开始执行时间:" + job.startTime);
System.out.println("完成时间:" + job.endTime);
System.out.println("周转时间:" + job.cycleTime);
System.out.println("带权周转时间:" + job.weightedTurnaroundTime);
System.out.println();
cycleTimeSum = cycleTimeSum.add(BigDecimal.valueOf(job.cycleTime));
weightedTurnaroundTimeSum = weightedTurnaroundTimeSum.add(job.weightedTurnaroundTime);
}
/**
* 加载times时间已经到达的任务到readyJobs
*/
private static void load() {
Iterator<Job> iterator = jobs.iterator();
while (iterator.hasNext()) {
Job job = iterator.next();
if (job.arrivalTime <= times) {
iterator.remove();
job.status = JobStatus.R;
readyJobs.addLast(job);
}
}
}
/**
* 统计信息
*/
private static void total() {
System.out.println();
System.out.println("平均周转时间:" + cycleTimeSum
.divide(BigDecimal.valueOf(count), MathContext.DECIMAL32));
System.out.println("平均带权周转时间:" + weightedTurnaroundTimeSum
.divide(BigDecimal.valueOf(count), MathContext.DECIMAL32));
}
public static void main(String[] args) {
firstComeFirstService();
// shortestJobFirst();
// highestResponseRatioNext();
total();
}
/**
* 先进先出
*/
private static void firstComeFirstService() {
addJob(0, 4);
addJob(1, 3);
addJob(2, 5);
addJob(3, 2);
addJob(4, 4);
// 初始化就绪任务队列
load();
// 如果times=0时没有任务被加载,那么times++,直到有任务被加载位置
while (readyJobs.isEmpty()) {
++times;
load();
}
while (!readyJobs.isEmpty()) {
Job job = readyJobs.poll();
running(job);
}
}
/**
* 最短任务优先
*/
private static void shortestJobFirst() {
addJob(0, 4);
addJob(1, 3);
addJob(2, 5);
addJob(3, 2);
addJob(4, 4);
// 初始化就绪任务队列
load();
// 如果times=0时没有任务被加载,那么times++,直到有任务被加载位置
while (readyJobs.isEmpty()) {
++times;
load();
}
while (!readyJobs.isEmpty()) {
Job minJob = null;
int minServiceTime = Integer.MAX_VALUE;
for(Job job : readyJobs) {
if (job.serviceTime < minServiceTime) {
minJob = job;
minServiceTime = job.serviceTime;
}
}
readyJobs.remove(minJob);
running(minJob);
}
}
/**
* 高响应比优先调度算法
*/
private static void highestResponseRatioNext() {
addJob(0, 3);
addJob(2, 6);
addJob(4, 4);
addJob(6, 5);
addJob(8, 2);
// 初始化就绪任务队列
load();
// 如果times=0时没有任务被加载,那么times++,直到有任务被加载位置
while (readyJobs.isEmpty()) {
++times;
load();
}
while (!readyJobs.isEmpty()) {
Job bestJob = null;
BigDecimal bestJobRatio = BigDecimal.ZERO;
for(Job job : readyJobs) {
// 计算当前任务的响应比 (等待时间 / 服务时间) + 1
BigDecimal ratio = BigDecimal.valueOf(times - job.arrivalTime)
.divide(BigDecimal.valueOf(job.serviceTime), MathContext.DECIMAL32)
.add(BigDecimal.ONE);
if (ratio.compareTo(bestJobRatio) > 0) {
bestJobRatio = ratio;
bestJob = job;
}
}
readyJobs.remove(bestJob);
running(bestJob);
}
}
}