. 首先,我来介绍一下该程序大致内容
- 程序使用了ArrayList链表来模拟各进程队列,并且结果会显示出每个时刻的进程的运行信息、最后的所有进程的执行结果和进程的执行顺序。
- ps:各个模拟程序是相互独立,如果不需要的直接删除即可。
现在介绍每个调度算法的思想
非抢占式先来先到:首先初始化变量,当后备队列和就绪队列都不为空时,按照达到时间顺序执行,执行的每一时刻都要判断是否有到达的进程,如果有,就插入到就绪队列中,然后循环往复,直到后备队列和就绪队列都为空为止。这里我们需要处理几个特殊情况:
一:同时到达的多个进程,按照默认排序执行。
二:当就绪队列无进程运行,这时后备队列还有进程
public void FCFS(ArrayList<PCB> p) {
if (!init(p))
return;
while (!(processPoolList.isEmpty() && processReadyList.isEmpty())) { // 进程的运行过程
PCB process = processReadyList.get(0);
process.setState("Running");
informationProcess(process);// 当前进程信息
for (int i = process.getAllTime() - 1, j = 1; i >= 0; j++, i--) { // 进程运行阶段
process.setAllTime(i);// 所需要的cup的时间减减
process.setCupTime(j);// 已占cup的时间加加
t++;// 模拟时间增加
System.out.println(t + "\t\t" + process.getId() + "\t\t" + process.getAllTime() + "\t\t"
+ process.getCupTime() + "\t\t" + process.getState());
try {
Thread.sleep(500); // 睡眠
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (!processPoolList.isEmpty()) {// 找该时刻到达的进程
insertProcess();
}
if (i == 1)
process.setState("End");// 进程结束
}
System.out.println("進程" + process.getId() + "運行結束");
result(process);
sequence[flag++]=processReadyList.get(0).getId();
processReadyList.remove(0); // 移除已经运行玩的进程
if (processReadyList.isEmpty() && !processPoolList.isEmpty()) {// 如果就绪“队列”为空,这找到下一个
t = processPoolList.get(0).getProcessArrivalTime();
insertProcess();
}
}
show();// 显示FCFS算法的最终结果
}
非抢占式短作业:首先初始化变量,当后备队列和就绪队列都不为空时,判断是否存在多个已到进程,若存在,按照服务时间短的优先执行,若不存在,按照达到时间顺序执行,在执行进程的过程中,每一时刻都要判断是否有到达的进程,如果有,就插入到就绪队列中。然后重复上述操作,直到后备队列和就绪队列都为空为止。这里我们需要处理几个特殊情况:
一:同时到达的多个进程。按照短服务时间优先原则
二:当就绪队列无进程运行,这时后备队列还有进程
public void SJF(ArrayList<PCB> p) {
if (!init(p))
return;
if (processReadyList.size() > 1) {// 处理同时达到的多个进程
for (int i = 1; i < processReadyList.size(); i++) {// 找到中先到且时间最短的进程
if (processReadyList.get(i).getProcessServiceTime() < processReadyList.get(i - 1)
.getProcessServiceTime())
index = i;
}
}
while (!(processPoolList.isEmpty() && processReadyList.isEmpty())) { // 进程的运行过程
PCB process = processReadyList.get(index);
process.setState("Running");
informationProcess(process);// 当前进程信息
for (int i = process.getAllTime() - 1, j = 1; i >= 0; j++, i--) { // 进程运行阶段
process.setAllTime(i);// 所需要的cup的时间减减
process.setCupTime(j);// 已占cup的时间加加
t++;
System.out.println(t + "\t\t" + process.getId() + "\t\t" + process.getAllTime() + "\t\t"
+ process.getCupTime() + "\t\t" + process.getState());
try {
Thread.sleep(500); // 睡眠
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (!processPoolList.isEmpty()) {// 找该时刻到达的进程
insertProcess();
}
if (i == 1)
process.setState("End");// 进程结束
}
System.out.println("進程" + process.getId() + "運行結束");
result(process);
sequence[flag++]=processReadyList.get(index).getId();
processReadyList.remove(index); // 移除已经运行完的进程
if (processReadyList.isEmpty() && !processPoolList.isEmpty()) {// 如果就绪“队列”为空,这找到下一个
t = processPoolList.get(0).getProcessArrivalTime();
insertProcess();
}
if (processReadyList.size() > 1) { // 判断就绪"队列"中的进程数,如果大于1,则找到服务时间最短的进程
index = 0;
for (int j = 1; j < processReadyList.size(); j++) {
if (processReadyList.get(index).getProcessServiceTime() > processReadyList.get(j)
.getProcessServiceTime())
index = j;
}
} else
index = 0;
}
show();// 显示JSF算法的最终结果
}
非抢占式高响应比:首先初始化变量,当后备队列和就绪队列都不为空时,判断是否存在多个已到进程,若存在,计算进程此时的优先级,按照高优先级先执行原则,若不存在,按照达到时间顺序执行,在执行进程的过程中,每一时刻都要判断是否有到达的进程,如果有,就插入到就绪队列中。然后重复上述操作,直到后备队列和就绪队列都为空为止。这里我们需要处理几个特殊情况:
一:同时到达的多个进程。按照优先级高优先原则,优先级一样,则按照短作业优先,若两个都一样,则按照到到达时间
二:当就绪队列无进程运行,这时后备队列还有进程
public void HRRN(ArrayList<PCB> p) {
index = 0;
if (!init(p))
return;
if (processReadyList.size() > 1) {// 处理同时达到的多个进程
for (int i = 1; i < processReadyList.size(); i++) {// 找到中先到且时间最短的进程
if (processReadyList.get(i).getProcessServiceTime() < processReadyList.get(i - 1)
.getProcessServiceTime())
index = i;
}
}
while (!(processPoolList.isEmpty() && processReadyList.isEmpty())) { // 进程的运行过程
PCB process = processReadyList.get(index);
process.setState("Running");
System.out.println("当前运行进程" + process.getId());
System.out.println("当前时间\t\t进程ID\t\tAllTime\t\tcpuTime\t\tpriority\tState");
System.out.print(t + "\t\t" + process.getId() + "\t\t" + process.getAllTime() + "\t\t"
+ process.getCupTime() + "\t\t");
System.out.printf("%.2f\t\t%s\n", process.getPriority(), process.getState());
for (int i = process.getAllTime() - 1, j = 1; i >= 0; j++, i--) {
process.setAllTime(i);// 所需要的cup的时间减减
process.setCupTime(j);// 已占cup的时间加加
t++;
System.out.print(t + "\t\t" + process.getId() + "\t\t" + process.getAllTime() + "\t\t"
+ process.getCupTime() + "\t\t");
System.out.printf("%.2f\t\t%s\n", process.getPriority(), process.getState());
try {
Thread.sleep(500); // 睡眠
} catch (InterruptedException e) {
}
if (!processPoolList.isEmpty()) {// 找该时刻到达的进程
insertProcess();
}
if (i == 1)
process.setState("End");// 进程结束
}
System.out.println("進程" + process.getId() + "運行結束");
result(process);
sequence[flag++]=processReadyList.get(index).getId();
processReadyList.remove(index); // 移除已经运行玩的进程
if (processReadyList.isEmpty() && !processPoolList.isEmpty()) {// 如果就绪“队列”为空,这找到下一个
t = processPoolList.get(0).getProcessArrivalTime();
insertProcess();
}
index = 0;
if (processReadyList.size() > 1) {// 判断就绪"队列"的个数是否大于1,如果是,求出各进程优先级,并找出优先级最高的进程
System.out.println("当前就绪对列中各进程的优先级");
for (int i = 0; i < processReadyList.size(); i++) {
double temp = 1 + (t - processReadyList.get(i).getProcessArrivalTime())
/ (double) processReadyList.get(i).getProcessServiceTime();
System.out.print("进程" + processReadyList.get(i).getId());
System.out.printf("\t优先权:%.2f\n", temp);
processReadyList.get(i).setPriority(temp);
}
for (int i = 0; i < processReadyList.size(); i++) {
if (processReadyList.get(index).getPriority() < processReadyList.get(i).getPriority())
index = i;
else if(processReadyList.get(index).getPriority() == processReadyList.get(i).getPriority()&&processReadyList.get(index).getProcessServiceTime()<processReadyList.get(i).getProcessServiceTime()){
index=i;
}
}
}
}
show();// 显示HRRN算法的最终结果
}
时间片轮转:首先初始化变量,然后按照到达时间顺序执行,当进程用完时间片或者进程执行完了,则进程插入就绪队列尾部或者将进程移除,然后重复上述操作,直到后备队列和就绪队列都为空为止。这里我们需要处理几个特殊情况:
一:同时到达的多个进程。按默认排列顺序执行。
二:当就绪队列无进程运行,这时后备队列还有进程
public void RR(ArrayList<PCB> p) {
int slie=1;
if (!init(p))
return;
while (!(processPoolList.isEmpty() && processReadyList.isEmpty())) { // 进程的运行过程
PCB process = processReadyList.get(0);
process.setState("Running");
informationProcess(process);// 当前进程信息
process.setAllTime(process.getAllTime() - slie);// 进程运行阶段
process.setCupTime(process.getCupTime() + slie);
t+=slie;
if (!processPoolList.isEmpty()) {// 找该时刻到达的进程
insertProcess();
}
if (process.getAllTime() == 0) {
result(process);
process.setState("End");
} else {
processReadyList.add(process);
}
System.out.println(t + "\t\t" + process.getId() + "\t\t" + process.getAllTime() + "\t\t"
+ process.getCupTime() + "\t\t" + process.getState());
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
sequence[flag++]=processReadyList.get(0).getId();
processReadyList.remove(0); // 移除已经运行完的进程
if (processReadyList.isEmpty() && !processPoolList.isEmpty()) {// 如果就绪“队列”为空,这找到下一个
t = processPoolList.get(0).getProcessArrivalTime();
insertProcess();
}
}
show();// 显示RR算法的最终结果
}
最后介绍一下进程控制块的内容PCB:
package xin03;
public class PCB {
private String id; // 进程标识数
private double priority = 50; // 进程优先数,并规定优先数越大的进程,其优先权
private int cupTime; // 进程已占CPU时间
private int allTime; // 进程还需要占用CPU时间。当进程运行完毕时,allTime变为0
private String state; // 进程状态
private int processArrivalTime;// 进程到达时间
private int processServiceTime;// 进程服务时间
private int finished;//进程的完成时间
private double processWeightedTurnoverTime;//进程的带权周转时间
private int processTurnoverTime;//进程的周转时间
public PCB() {
}
public PCB(String id, int processArrivalTime, int processServiceTime, String state) {
super();
this.id = id;
this.processServiceTime = processServiceTime;
this.processArrivalTime = processArrivalTime;
this.state = state;
this.allTime=processServiceTime;
}
public int getFinished() {
return finished;
}
public void setFinished(int finished) {
this.finished = finished;
}
public double getProcessWeightedTurnoverTime() {
return processWeightedTurnoverTime;
}
public void setProcessWeightedTurnoverTime(double processWeightedTurnoverTime) {
this.processWeightedTurnoverTime = processWeightedTurnoverTime;
}
public int getProcessTurnoverTime() {
return processTurnoverTime;
}
public void setProcessTurnoverTime(int processTurnoverTime) {
this.processTurnoverTime = processTurnoverTime;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public double getPriority() {
return priority;
}
public void setPriority(double priority) {
this.priority = priority;
}
public int getCupTime() {
return cupTime;
}
public void setCupTime(int cupTime) {
this.cupTime = cupTime;
}
public int getAllTime() {
return allTime;
}
public void setAllTime(int allTime) {
this.allTime = allTime;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public int getProcessArrivalTime() {
return processArrivalTime;
}
public void setProcessArrivalTime(int processArrivalTime) {
this.processArrivalTime = processArrivalTime;
}
public int getProcessServiceTime() {
return processServiceTime;
}
public void setProcessServiceTime(int processServiceTime) {
this.processServiceTime = processServiceTime;
}
}
这是测试程序:
package xin03;
import java.util.ArrayList;
import java.util.Scanner;
public class Text {
public static void main(String[] args) throws Exception {
showTable();
}
public static void showTable() {
Scanner sr1 = new Scanner(System.in);
Process process = new Process();
show();
int s = 0;
while (true) {
try {
s = sr1.nextInt();
} catch (Exception e) {
sr1.nextLine();
continue;
}
switch (s) {
case 1:
process.FCFS(input());
break;
case 2:
process.SJF(input());
break;
case 3:
process.HRRN(input());
break;
case 4:
process.RR(input());
break;
case 5:
show();
break;
case 6:
sr1.close();
System.exit(0);
default:
System.out.println("");
}
}
}
public static void show() {
System.out.println("**********************************************");
System.out.println(" 1.FSFC算法 ");
System.out.println(" 2.JSF算法 ");
System.out.println(" 3.HRRH算法 ");
System.out.println(" 4.RR算法 ");
System.out.println(" 5.显示菜单 ");
System.out.println(" 6.退出 ");
System.out.println("**********************************************");
System.out.print("请输入选项:");
}
public static ArrayList<PCB> input() {
Scanner sr = new Scanner(System.in);
ArrayList<PCB> processList = new ArrayList<PCB>();
System.out.println("请输入进程信息(进程id 进程到达时间 进程服务时间)以end结束:");
while (true) {
try {
String a = sr.next();
if ("end".equalsIgnoreCase(a))
break;
processList.add(new PCB(a, sr.nextInt(), sr.nextInt(), "Ready"));
} catch (Exception e) {
sr.nextLine();
System.out.println("输入有误!请重新输入");
}
}
if (!processList.isEmpty()) {// 判空操作
for (int i = 0; i < processList.size() - 1; i++) {// 选择排序对链表中元素按到达时间排序
for (int j = i + 1; j < processList.size(); j++) {
if (processList.get(i).getProcessArrivalTime() > processList.get(j).getProcessArrivalTime()) {
PCB process = processList.get(j);
processList.set(j, processList.get(i));
processList.set(i, process);
}
}
}
}
return processList;
}
}
ps:如果各位大佬发现有什么不足的地方或者有需要代码的同学,请留言哟!!!!