【計算機作業系統】用java模擬非搶佔式(先來先到、短作業、高響應比),時間片輪轉排程演算法
. 首先,我來介紹一下該程式大致內容
- 程式使用了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:如果各位大佬發現有什麼不足的地方或者有需要程式碼的同學,請留言喲!!!!