短进程优先算法(SJF):shortest job first
算法描述:每次选出最短的进程进行调度,调度完毕则淘汰,直到所有进程都调度完毕。
思维导图:

例题: 对如下进程 使用SJF算法 进行排序和结果回显

正确结果:
施行SPF(非抢占式)算法:
SPF的进程调度顺序为进程1、3、4、2,
平均进程周转时间T = (20+15+20+45)/4 = 25
平均带权进程周转时间W = (20/20+15/5+20/10+45/15)/4 = 2.25
Java实现:
package com.dhl.beyond.os_sjf;
import java.util.Scanner;
public class SJF {
String name;
double arrivetime;
double servicetime;
double starttime;
double finishtime;
double zztime;
double dqzztime;
public SJF(){ }
public SJF(String name, double arrivetime, double servicetime) {
this.name = name;
this.arrivetime = arrivetime;
this.servicetime = servicetime;
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("===============短进程优先调度算法========================");
System.out.println("输入进程数目: ");
int num = scanner.nextInt();
SJF[] p = new SJF[num];
System.out.println("请创建进程对象, 输入进程名称 到达时间 服务时间 <例如: p1 0 20>");
for (int i= 0; i<p.length; i++){
System.out.println("请输入进程:" +(i+1)+"的信息: ");
p[i] = new SJF(scanner.next(), scanner.nextDouble(),scanner.nextDouble());
}
OS_SJF(p);
scanner.close();
}
private static void OS_SJF(SJF[] p) {
sort(p);
run(p);
print(p);
double Attime=0 ,AQttime = 0;
for (int k=0; k<p.length;k++){
Attime += p[k].zztime;
AQttime += p[k].dqzztime;
}
Attime = Attime/p.length;
AQttime = AQttime/p.length;
System.out.println("调用短进程优先的平均周转时间为: "+Attime);
System.out.println("调用短进程优先的平均带权周转时间为: "+AQttime);
}
public static void sort(SJF[] p) {
for (int i = 0; i < p.length; i++) {
for (int j = i + 1; j < p.length; j++) {
if (p[i].arrivetime > p[j].arrivetime) {
SJF temp;
temp = p[i];
p[i] = p[j];
p[j] = temp;
}
}
}
for (int m = 0; m < p.length; m++) {
if (m == 0)
p[m].finishtime = p[m].arrivetime + p[m].servicetime;
else
p[m].finishtime = p[m - 1].finishtime + p[m].servicetime;
int i = 0;
for (int n = m + 1; n < p.length; n++) {
if (p[n].arrivetime <= p[m].finishtime) {
i++;
}
int next = m + 1;
double min = p[m + 1].servicetime;
for (int k = m + 2; k <= m + i; k++) {
if (p[k].servicetime < min) {
min = p[k].servicetime;
next = k;
SJF temp;
temp = p[m + 1];
p[m + 1] = p[next];
p[next] = temp;
}
}
}
}
}
private static void run(SJF[] p) {
for(int k=0; k<p.length;k++){
if (k==0){
p[k].starttime = p[k].arrivetime;
p[k].finishtime = p[k].arrivetime+p[k].servicetime;
}else{
p[k].starttime = p[k-1].finishtime;
p[k].finishtime = p[k-1].finishtime+p[k].servicetime;
}
}
for (int k=0; k<p.length;k++){
p[k].zztime = p[k].finishtime-p[k].arrivetime;
p[k].dqzztime=p[k].zztime/p[k].servicetime;
}
}
private static void print(SJF[] p) {
System.out.println("调用短进程优先算法后 进程运行的顺序是: ");
System.out.println(p[0].name);
for (int k=1;k<p.length;k++){
System.out.print("-->"+p[k].name);
}
System.out.println("");
System.out.println("具体的调度信息: ");
System.out.println("进程名 到达时间 服务时间 开始时间 结束时间 周转时间 带权周转时间");
for(int k =0;k<p.length;k++){
System.out.printf("%4s",p[k].name);
System.out.printf("%10.3f",p[k].arrivetime);
System.out.printf("%10.3f",p[k].servicetime);
System.out.printf("%10.3f",p[k].starttime);
System.out.printf("%10.3f",p[k].finishtime);
System.out.printf("%10.3f",p[k].zztime);
System.out.printf("%10.3f\n",p[k].dqzztime);
}
}
}
测试结果
