目录
一、算法原理
几种常用的调度算法原理
1.先来先服务(FCFS)
当作业调度采用该算法时,系统将按作业先后到达的次序来进行调度,或者说它是优先选择等待时间长的作业,将他们调入内存,而不管作业执行时间的长短,只有当该进程执行完或发生某事件而阻塞后,进程调度程序才将处理机分配给其它进程。
2.非抢占式短作业优先(SPF)
以作业的长短来计算优先级,作业越短优先级越高,优先级越高的进程先执行,但是这种算法不是抢占式的,即如果有进程正在执行不能抢占处理机,而是要等进程执行完毕才能去调度优先级较高的进程先执行。
3.抢占式短作业优先(SJF)
原理与SPF基本相同,但是不同的是SJF是抢占式的,即如果有一个进程的执行时间比当前正在执行的进程的剩余时间少的话就抢占当前的进程
4.高响应比优先调度算法(HRRN)
为每一个作业(进程)引入一个动态优先级,这个动态优先级随时间而增大,每当一个进程执行完毕或约到阻塞时就要通过这个算法计算出下一个要执行的作业
计算公式为:优先权=(等待时间+要求服务时间)/要求服务时间
二、实验示例
下面以FCFS为举例展示
process
Arrival Time
Brust Time
p1
0
3
p2
2
6
p3
4
4
p4
6
5
p5
8
2
分别计算出上表5个进程完成时间、周转时间、带权周转时间,并计算出平均周转时间和平均带权周转时间。
周转时间 = 完成时间 - 到达时间
带权周转时间 = 周转时间 / 完成一个进程需要的时间
三、具体代码
import java.util.Scanner;
public class ThreadDispatch {
public static void FCFS(work[] works){
System.out.println("先来先服务模拟开始。。。。");
work w;
for(int i = 0;i < works.length;i++){//按照冒泡排序按照到达时间进行升序排列
for (int j = 0; j < works.length - i - 1; j++) {
if(works[j].arrivalTime > works[j+1].arrivalTime){
w = works[j];
works[j] = works[j+1];
works[j+1] = w;
}
}
}
double totalTime = 0;//记录时间
double[] turnTimes = new double[works.length];//记录每个进程的周转时间
double[] weightTurnTimes = new double[works.length];//记录每个进程的带权周转时间
for (int i = 0; i < works.length; i++) {
System.out.println("当前时间: " + totalTime + ", " + works[i].processName + "开始运行" + "* * * * * *,运行时间为:" + works[i].burstTime);
totalTime += works[i].burstTime;//完成时间
double turnTime = totalTime-works[i].arrivalTime;//周转时间
turnTimes[i] = turnTime; //记录每个进程的周转时间
double weightTurnTime = turnTime/works[i].burstTime;//带权周转时间
weightTurnTimes[i] = weightTurnTime;
System.out.println("完成时间:" + totalTime + "\t周转时间:" + turnTime + "\t带权周转时间: " + weightTurnTime);
System.out.println("\n");
}
double tempTurnTimes = 0; //为计算平均周转时间
for (int i = 0; i < weightTurnTimes.length; i++) {
tempTurnTimes += turnTimes[i];
}
double tempweightTurnTimes = 0; //为计算平均带权周转时间
for (int i = 0; i < weightTurnTimes.length; i++) {
tempweightTurnTimes += weightTurnTimes[i];
}
System.out.println("平均周转时间为:" + tempTurnTimes/works.length + ",平均带权周转时间为:" + tempweightTurnTimes/works.length);
}
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.print("输入要执行的进程个数:");
int n = scan.nextInt();
work[] works = new work[n];
System.out.println("请分别输入processName arrivalTime burstTime");
for(int i = 0;i < n;i++){
String name = scan.next();
double time1 = scan.nextDouble();
double time2 = scan.nextDouble();
works[i] = new work(name,time1,time2);
}
// System.out.println("展示线程的信息:");
// for(int i = 0;i<n;i++){
// System.out.println(works[i].processName + " " + works[i].arrivalTime + " " + works[i].burstTime);
// }
FCFS(works);
}
}
class work{
String processName; //进程名
double arrivalTime; //一个作业或进程到达的时间
double burstTime; //进程执行需要的时间
public work(String processName,double arrivalTime,double burstTime){
this.arrivalTime = arrivalTime;
this.burstTime = burstTime;
this.processName = processName;
}
}