一、算法思想
1、先来先服务:
先来先服务(FCFS)调度算法是一种最简单的调度算法,该算法既可用于作业调度,也可用于进程调度。当在作业调度中采用该算法时,系统将按照作业到达的先后次序进行调度,从后备作业队列中选择几个最先进入该队列的作业,将它们调入内存,为它们分配资源和创建进程。然后把它们放入就绪队列。
2、短作业优先调度:
SJF算法是以作业的长短来计算优先级,作业越短,其优先级越高。作业的长短是以作业所要求的运行时间来衡量的。SJF 算法可以分别用于作业调度和进程调度。在把短作业优先调度算法用于作业调度时,它将从外存的作业后备队列中选择若干个估计运行时间最短的作业,优先将它们调入内存运行。
二、程序代码
1、先来先服务代码:
package Package8;
import java.util.Scanner;
/**
* 先来先服务
*/
public class Demo1 {
public static void main(String[] args) {
JCB[] a = new JCB[10];
Scanner scanner = new Scanner(System.in);
int k = 0; // 初始化
System.out.println("请一次输入两个整数,之间用空格隔开,输入负数结束输入");
// 重复输入进程信息
while (true){
System.out.printf("请输入第%d进程到达时间、服务时间:", k);
// 进程id设置为k
double arriveTime = scanner.nextDouble();
if (arriveTime < 0){
System.out.println("输入结束");
break;
}
double serviceTime = scanner.nextDouble();
a[k] = new JCB(k,arriveTime, serviceTime); // 利用构造方法初始化数据
k ++;
if (serviceTime < 0){
System.out.println("输入结束");
break;
}
}
scanner.close(); // 释放scanner
// 输出初始作业状态
System.out.println("初始作业状态:");
for (int i = 0; i < k; i++) {
System.out.println(a[i]);
}
// 冒泡排序,按照到达时间从小到大排序
for (int i = 0; i < k; i++) {
for (int j = 0; j + 1 < k - i; j++) {
if (a[j].getArriveTime() > a[j + 1].getArriveTime()){
JCB temp = new JCB();
temp = a[j];
a[j] = a[j + 1];
a[j + 1] = temp;
}
}
}
// 遍历数组,利用算法完善数据并输出结果
System.out.println();
System.out.println("调度过程及调度后作业状态:");
for (int i = 0; i < k; i++) {
if (i == 0){
a[i].setFinishTime(a[i].getArriveTime() + a[i].getServiceTime());
a[i].setCyclingTime(a[i].getFinishTime() - a[i].getArriveTime());
// 将结果保留两位小数
double time = a[i].getCyclingTime() / a[i].getServiceTime();
a[i].setFloat_Wi(Double.parseDouble(String .format("%.2f", time)));
} else {
if (a[i].getArriveTime() > a[i - 1].getFinishTime()){
a[i].setFinishTime(a[i].getArriveTime() + a[i].getServiceTime());
} else{
a[i].setFinishTime(a[i - 1].getFinishTime() + a[i].getServiceTime());
}
a[i].setCyclingTime(a[i].getFinishTime() - a[i].getArriveTime());
// 将结果保留两位小数
double time = a[i].getCyclingTime() / a[i].getServiceTime();
a[i].setFloat_Wi(Double.parseDouble(String .format("%.2f", time)));
}
// 遍历数组输出结果
System.out.println(a[i]);
}
}
public static class JCB{
private int id;
private double arriveTime; // 到达时间
private double serviceTime; // 服务时间
private double finishTime; // 完成时间
private double cyclingTime; // 周转时间
private double float_Wi; // 带权周转时间
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public double getArriveTime() {
return arriveTime;
}
public void setArriveTime(double arriveTime) {
this.arriveTime = arriveTime;
}
public double getServiceTime() {
return serviceTime;
}
public void setServiceTime(double serviceTime) {
this.serviceTime = serviceTime;
}
public double getFinishTime() {
return finishTime;
}
public void setFinishTime(double finishTime) {
this.finishTime = finishTime;
}
public double getCyclingTime() {
return cyclingTime;
}
public void setCyclingTime(double cyclingTime) {
this.cyclingTime = cyclingTime;
}
public double getFloat_Wi() {
return float_Wi;
}
public void setFloat_Wi(double float_Wi) {
this.float_Wi = float_Wi;
}
public JCB() {
}
public JCB(int id, double arriveTime, double serviceTime) {
this.id = id;
this.arriveTime = arriveTime;
this.serviceTime = serviceTime;
}
@Override
public String toString() {
return "进程信息:" +
"id=" + id +
", 到达时间=" + arriveTime +
", 服务时间=" + serviceTime +
", 完成时间=" + finishTime +
", 周转时间=" + cyclingTime +
", 带权周转时间=" + float_Wi;
}
}
}
运行结果:
2、短作业优先调度代码:
package Package8;
import java.util.Scanner;
/**
* 短作业优先
*/
public class Demo2 {
public static void main(String[] args) {
JCB2[] a = new JCB2[10];
Scanner scanner = new Scanner(System.in);
int k = 0; // 初始化,k记录总进程数
System.out.println("请一次输入两个整数,之间用空格隔开,输入负数结束输入");
// 重复输入进程信息
while (true){
System.out.printf("请输入第%d进程到达时间、服务时间:", k);
// 将进程id设置为k
double arriveTime = scanner.nextDouble();
if (arriveTime < 0){
System.out.println("输入结束");
break;
}
double serviceTime = scanner.nextDouble();
a[k] = new JCB2(k,arriveTime, serviceTime); // 利用构造方法初始化数据
k ++;
if (serviceTime < 0){
System.out.println("输入结束");
break;
}
}
scanner.close(); // 释放scanner
// 输出初始作业状态
System.out.println("初始作业状态");
for (int i = 0; i < k; i++) {
System.out.println(a[i]);
}
// 找出最早到达的进程,优先调度
JCB2 min = new JCB2();
min = a[0];
int m = 0; // 用于记录最早到达进程的id(下标)
for (int i = 0; i < k; i++) {
if (a[i].getArriveTime() < min.getArriveTime()){
min = a[i];
m = i;
} else if(a[i].getArriveTime() == min.getArriveTime() && a[i].getServiceTime() < min.getServiceTime()){
min = a[i];
m = i;
}
}
JCB2 temp1 = new JCB2();
temp1 = a[0];
a[0] = min;
a[m] = temp1;
// 冒泡排序,除第0个进程外按照服务时间从小到大排序
for (int i = 0; i < k; i++) {
for (int j = 1; j + 1 < k - i; j++) {
if (a[j].getServiceTime() > a[j + 1].getServiceTime()){
JCB2 temp = new JCB2();
temp = a[j];
a[j] = a[j + 1];
a[j + 1] = temp;
}
}
}
// 遍历数组,利用算法完善数据并输出结果
System.out.println();
System.out.println("调度过程及调度后作业状态:");
for (int i = 0; i < k; i++) {
if (i == 0){
a[i].setFinishTime(a[i].getArriveTime() + a[i].getServiceTime());
a[i].setCyclingTime(a[i].getFinishTime() - a[i].getArriveTime());
// 将结果保留两位小数
double time = a[i].getCyclingTime() / a[i].getServiceTime();
a[i].setFloat_Wi(Double.parseDouble(String .format("%.2f", time)));
} else {
if (a[i].getArriveTime() > a[i - 1].getFinishTime()){
a[i].setFinishTime(a[i].getArriveTime() + a[i].getServiceTime());
} else{
a[i].setFinishTime(a[i - 1].getFinishTime() + a[i].getServiceTime());
}
a[i].setCyclingTime(a[i].getFinishTime() - a[i].getArriveTime());
// 将结果保留两位小数
double time = a[i].getCyclingTime() / a[i].getServiceTime();
a[i].setFloat_Wi(Double.parseDouble(String .format("%.2f", time)));
}
// 遍历数组输出结果
System.out.println(a[i]);
}
}
public static class JCB2{
private int id;
private double arriveTime; // 到达时间
private double serviceTime; // 服务时间
private double finishTime; // 完成时间
private double cyclingTime; // 周转时间
private double float_Wi; // 带权周转时间
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public double getArriveTime() {
return arriveTime;
}
public void setArriveTime(double arriveTime) {
this.arriveTime = arriveTime;
}
public double getServiceTime() {
return serviceTime;
}
public void setServiceTime(double serviceTime) {
this.serviceTime = serviceTime;
}
public double getFinishTime() {
return finishTime;
}
public void setFinishTime(double finishTime) {
this.finishTime = finishTime;
}
public double getCyclingTime() {
return cyclingTime;
}
public void setCyclingTime(double cyclingTime) {
this.cyclingTime = cyclingTime;
}
public double getFloat_Wi() {
return float_Wi;
}
public void setFloat_Wi(double float_Wi) {
this.float_Wi = float_Wi;
}
public JCB2() {
}
public JCB2(int id, double arriveTime, double serviceTime) {
this.id = id;
this.arriveTime = arriveTime;
this.serviceTime = serviceTime;
}
@Override
public String toString() {
return "进程信息:" +
"id=" + id +
", 到达时间=" + arriveTime +
", 服务时间=" + serviceTime +
", 完成时间=" + finishTime +
", 周转时间=" + cyclingTime +
", 带权周转时间=" + float_Wi;
}
}
}