先进先出
直接根据等待时间调度任务。当任务被加载后,最先加载进来的最先调度。
最短任务优先
直接根据服务时间调度任务。当多个任务在加载队列中,查询最短服务时间的任务先调度。
最高响应比优先
根据等待时间和服务时间调度任务。
响应比:(等待时间 + 服务时间) / 服务时间
当多个任务在加载队列中,查询响应比最高的任务先调度。
代码实现
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);
}
}
}