这次的实验跟上次类似,只不过多加了多道的概念。
依旧是下面几个算法:
采用先来先服务(FCFS)
最短作业优先(SJF)
响应比高者优先(HRN)
运行结果如下:
代码如下:
import java.util.LinkedList;
import java.util.Queue;
public class source {
public static void main(String args[]) {
Control control = new Control();
control.FCFS();
System.out.println("\n\n");
control.SJF();
System.out.println("\n\n");
control.HRRF();
}
}
class Control{
private JCB job[];
private int size = 5;
private int timeSimulator = 0;
private int systemMachine = 4;//系统资源数
private int systemRAM = 100;
private boolean jump[];//资源不满足的应该跳过
Queue<JCB> waitExec = new LinkedList<JCB>();//定义一个队列储存目前系统可以满足其需求的作业
class JCB{
StringBuffer name = new StringBuffer("");//作业名
int order;//记录作业的初始位置
int ramRequire;//所需资源数
int machineRequire;
boolean beenVisited;//判断该作业是否已经被执行过
boolean enterQueue;//判断该作业是否已经进入了就绪队列状态
int enterSystemTime;//进入输入井的时间
int beginWorkTime;//调入主存的时间(在单道调度中即位进入cpu的时间)
int runTime;//运行所需时间
int FinishTime;//完成时间
int totalTime;//周转时间
int enterMemoryTime;
double weightTotalTime;//带权周转时间
double responceRate = 0;//响应比
}
public boolean checkSatisfy(int i) {
if(job[i].beenVisited == true)
return false;
if(job[i].enterSystemTime > timeSimulator)
return false;
if(job[i].enterQueue == true)
return false;
if(job[i].ramRequire > systemRAM||job[i].machineRequire > systemMachine)
return false;
return true;
}
//先来先服务算法(多道)
//1、先检查当前时间段进入输入井的作业哪些作业能够满足要求(遍历)
//2、将能够满足请求的作业按先来先服务的顺序推入队列中
//3、执行一个队列中的队首作业后释放作业占有的系统资源再重复第一步骤
public void FCFS() {
int numExec = size;
JCB temp;
System.out.println("FCFS调度算法");
initial();
//检查当前时间段进入输入井的作业哪些作业能够满足要求
while(numExec > 0) {
for(int i = 0;i < size;i++) {
if(checkSatisfy(i) == true) {
if(job[i].enterQueue == false) {
job[i].enterQueue = true;
System.out.println(job[i].name + "要求的资源能够满足,进入主存");
waitExec.add(job[i]);
job[i].enterMemoryTime = timeSimulator;
systemRAM -= job[i].ramRequire;
systemMachine -= job[i].machineRequire;
}
}
}
if(waitExec.peek() != null) {
temp = waitExec.poll();
System.out.println(temp.name + "开始执行...");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
temp.beenVisited = true;
//释放资源
systemRAM += temp.ramRequire;
systemMachine += temp.machineRequire;
//设置作业开始执行和结束运行的时间
temp.beginWorkTime = timeSimulator;
temp.FinishTime = temp.beginWorkTime + temp.runTime;
timeSimulator = temp.FinishTime;
totalTime(temp.order);
calcWeightTotalTime(temp.order);
numExec--;
System.out.println(temp.name + "执行结束...");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//执行一个队列中的队首作业后释放作业占有的系统资源再重复第一步骤
}
System.out.println("\t\t FCFS调度算法运行结果");
try {
Thread.sleep(200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
printMess();
}
public void totalTime(int i) {
job[i].totalTime = job[i].FinishTime - job[i].enterSystemTime;
}
public void calcWeightTotalTime(int i) {
job[i].weightTotalTime = job[i].totalTime*1.0 / job[i].runTime;
}
public void createJumpArray() {
jump = new boolean[size];
for(int i = 0;i < size;i++) {
if(checkSatisfy(i) == false) {
jump[i] = true;
}
}
}
//短作业优先算法
//1、先检查当前时间段进入输入井的作业哪些作业能够满足要求(遍历)
//2、将能够满足要求的作业按运行时间从短到长推入队列
//3、执行一个队列中的队首作业后释放作业占有的系统资源再重复第一步骤
public void SJF() {
System.out.println("SJF调度算法");
initial();
int minJob = -1;
// minJob = findMinJob();
int numExec = size;
JCB temp;
//检查当前时间段进入输入井的作业哪些作业能够满足要求
//应当从系统资源可满足的作业中选取最小作业
while(numExec > 0) {
for(int i = 0;i < size;i++) {
createJumpArray();
minJob = findMinJob();
if(minJob == -1)
{
break;
}
if(job[minJob].enterQueue == false) {
job[minJob].enterQueue = true;
System.out.println(job[minJob].name + "要求的资源能够满足,进入主存");
waitExec.add(job[minJob]);
job[minJob].enterMemoryTime = timeSimulator;
systemRAM -= job[minJob].ramRequire;
systemMachine -= job[minJob].machineRequire;
}
}
if(waitExec.peek() != null) {
temp = waitExec.poll();
System.out.println(temp.name + "开始执行...");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
temp.beenVisited = true;
//释放资源
systemRAM += temp.ramRequire;
systemMachine += temp.machineRequire;
//设置作业开始执行和结束运行的时间
temp.beginWorkTime = timeSimulator;
temp.FinishTime = temp.beginWorkTime + temp.runTime;
timeSimulator = temp.FinishTime;
totalTime(temp.order);
calcWeightTotalTime(temp.order);
numExec--;
System.out.println(temp.name + "执行结束...");
}
//执行一个队列中的队首作业后释放作业占有的系统资源再重复第一步骤
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("\t\t SJF调度算法运行结果");
try {
Thread.sleep(200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
printMess();
}
//找出最小的运行时间的作业
public int findMinJob() {
int min = 0;
int i;
for(i = 1;i < size;i++) {
if(jump[i] == false&&job[i].runTime < job[min].runTime) {
min = i;
}
}
return min;
}
//响应比最高优先算法
public void HRRF() {
System.out.println("HRRF调度算法");
initial();
int bestJob = -1;
// bestJob = findMinJob();
int numExec = size;
JCB temp;
//检查当前时间段进入输入井的作业哪些作业能够满足要求
//应当从系统资源可满足的作业中选取最小作业
while(numExec > 0) {
for(int i = 0;i < size;i++) {
createJumpArray();
bestJob = findBestResponceRate();
if(bestJob == -1) {
break;
}
if(job[bestJob].enterQueue == false) {
job[bestJob].enterQueue = true;
System.out.println(job[bestJob].name + "要求的资源能够满足,进入主存");
waitExec.add(job[bestJob]);
job[bestJob].enterMemoryTime = timeSimulator;
systemRAM -= job[bestJob].ramRequire;
systemMachine -= job[bestJob].machineRequire;
}
}
if(waitExec.peek() != null) {
temp = waitExec.poll();
System.out.println(temp.name + "开始执行...");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
temp.beenVisited = true;
//释放资源
systemRAM += temp.ramRequire;
systemMachine += temp.machineRequire;
//设置作业开始执行和结束运行的时间
temp.beginWorkTime = timeSimulator;
temp.FinishTime = temp.beginWorkTime + temp.runTime;
timeSimulator = temp.FinishTime;
totalTime(temp.order);
calcWeightTotalTime(temp.order);
numExec--;
System.out.println(temp.name + "执行结束...");
}
//执行一个队列中的队首作业后释放作业占有的系统资源再重复第一步骤
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("\t\t HRRF调度算法运行结果");
try {
Thread.sleep(200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
printMess();
}
//计算作业的响应比
public void calcResponceRate() {
for(int i = 0;i < size;i++) {
if(job[i].beenVisited == false && job[i].enterSystemTime <= timeSimulator) {
job[i].responceRate = (timeSimulator - job[i].enterSystemTime + job[i].runTime) * 1.0 / job[i].runTime;
}
}
}
//找出最高响应比的作业
public int findBestResponceRate() {
calcResponceRate();
int best = -1;
//找出第一个未被执行过的作业
int i;
for(i = 0;i < size;i++) {
if(jump[i] == false) {
best = i;
break;
}
}
for(int j = i;j < size;j++) {
if(jump[j] == false&&job[best].responceRate < job[j].responceRate) {
best = j;
}
}
return best;
}
//对作业进行初始化
public void initial() {
System.out.print("JOB表初始化中");
for(int i = 0;i < 40;i++) {
System.out.print(">");
try {
Thread.sleep(15);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("\n初始化成功!");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
timeSimulator = 0;
job = new JCB[size];
for(int i = 0;i < size;i++) {
job[i] = new JCB();
}
for(int i = 0;i < size;i++) {
job[i].name.append( "JOB" + (i+1));
job[i].order = i;
}
job[0].enterSystemTime = 0;
job[0].runTime = 40;
job[0].ramRequire = 35;
job[0].machineRequire = 3;
job[1].enterSystemTime = 10;
job[1].runTime = 30;
job[1].ramRequire = 70;
job[1].machineRequire = 1;
job[2].enterSystemTime = 15;
job[2].runTime = 20;
job[2].ramRequire = 50;
job[2].machineRequire = 3;
job[3].enterSystemTime = 35;
job[3].runTime = 10;
job[3].ramRequire = 25;
job[3].machineRequire = 2;
job[4].enterSystemTime = 40;
job[4].runTime = 5;
job[4].ramRequire = 20;
job[4].machineRequire = 2;
}
//打印作业平均周转时间
public double avgTotalTime() {
double sum = 0;
for(int i = 0;i < size;i++) {
sum += job[i].totalTime;
}
return sum*1.0 / size;
}
//打印作业总周转时间
public double calcTotalTime() {
double sum = 0;
for(int i = 0;i < size;i++) {
sum += job[i].totalTime;
}
return sum;
}
//打印作业带权平均周转时间
public double avgWeightTotalTime() {
double sum = 0;
for(int i = 0;i < size;i++) {
sum += job[i].weightTotalTime;
}
return sum*1.0 / size;
}
public double calcWeightTotalTime() {
double sum = 0;
for(int i = 0;i < size;i++) {
sum += job[i].weightTotalTime;
}
return sum;
}
//对作业表和调度表进行打印输出
public void printMess() {
System.out.println("作业名\t进入时间\t运行时间\t作业调度\t进程调度\t结束时间\t周转时间\t带权周转时间\t");
for(int i = 0;i < size;i++) {
System.out.println(" " + job[i].name + "\t" + " " + job[i].enterSystemTime + "\t" + " " + job[i].runTime + "\t"
+ " " + job[i].enterMemoryTime + "\t" + " " + job[i].beginWorkTime + "\t" + " " + job[i].FinishTime + "\t" + " " + job[i].totalTime + "\t" + " " + String.format("%.2f",job[i].weightTotalTime ) + "\t" );
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("\t\t\t\t\t\t" + " " +calcTotalTime() + "\t" + " " + String.format("%.2f",calcWeightTotalTime() ) + "\t");
System.out.println("平均周转时间"+"\t\t"+avgTotalTime()+"\n"+"作业平均带权周转时间"+"\t" + String.format("%.2f",avgWeightTotalTime()));
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}