使用java實現模擬程序排程
這本來是我的作業系統作業,斑竹本來想偷懶在網上找一篇交上去,但無奈沒有找到符合的,只好自己寫了。言歸正傳,在這個例子中,我實現了程序排程的三種演算法,分別是優先順序演算法,時間片演算法,和段作業優先演算法(fcfs演算法比較簡單,這裡就不做說明了,讀者可以根據斑竹的思路自己寫)。在寫這個程式的時候,斑竹感覺也挺麻煩的,沒有具體的思路,但第二天就要交了,沒辦法,斑竹在前一天晚上終於想通了關鍵。那就是,不論是哪一種演算法,只要能列出在個時間段當前在執行的程序就好了,剩下的求響應時間,週轉時間,甘特圖什麼的就一樣了。
廢話少說,這裡貼出程式碼,如果心急的朋友,可以直接去下載原始碼。
1.讀檔案,從txt檔案中讀取json格式的程序。我的json資料如下:
[
{
"name": "P1",
"startTime": 0,
"runTime": 7,
"priority": 5,
"isOver":false
},
{
"name": "P2",
"startTime": 1,
"runTime": 1,
"priority": 1,
"isOver":false
},
{
"name": "P3",
"startTime": 1,
"runTime": 3,
"priority": 4,
"is_over":false
},
{
"name": "P4",
"startTime": 2,
"runTime": 5,
"priority": 3,
"isOver":false
},
{
"name": "P5",
"startTime": 4,
"runTime": 4,
"priority": 2,
"isOver":false
}
]
主函式中讀取檔案的方法如下:
private static String loadProcess() {
URL xmlpath=MainRun.class.getClassLoader().getResource("");
String encoding="utf-8";
try {
File file=new File(xmlpath.toString().replace("file:/", "")+"com/box/process/JOB1.txt");
if(file.isFile() && file.exists()){
InputStreamReader read = new InputStreamReader(
new FileInputStream(file),encoding);
BufferedReader bufferedReader = new BufferedReader(read);
StringBuffer buffer=new StringBuffer();
String lineTxt = null;
while((lineTxt = bufferedReader.readLine()) != null){
buffer.append(lineTxt);
}
String message=buffer.toString();
read.close();
return message;
}else{
System.out.println("開啟檔案失敗");
}
} catch (Exception e) {
System.out.println("載入檔案失敗");
e.printStackTrace();
}
return null;
}
2.優先數演算法:
private static void priority(List<PCB> pcbs) {
List<String> queueList=new ArrayList<>();
System.out.println("排程佇列中每秒執行的程序如下:");
for(int i=0;i<allTime;i++){
PCB current=null;
int k=0;
for(int j=0;j<pcbs.size();j++){
PCB pcb=pcbs.get(j);
if(pcb.getIsOver()==false){
if(pcb.getStartTime()<=i){
if(current==null){
current=pcb;
}else{
if (current.getPriority()>pcb.getPriority()){
current=pcb;
k=j;
}
}
}
}
}
pcbs.get(k).decrease();
queueList.add(current.getName());
System.out.print(current.getName());
}
int j=0;
System.out.println("\n 優先演算法甘特圖如下:");
System.out.print("0 "+queueList.get(j)+" ");
for(int i=0;i<queueList.size();i++){
if(!queueList.get(i).equals(queueList.get(j))){
System.out.print(i+" "+queueList.get(i)+" ");
j=i;
}
}
System.out.print(" "+(queueList.size()));
System.out.println("\n程序名:\t"+"等待時間:\t"+"週轉時間:\t");
for(int i=0;i<pcbs.size();i++){
System.out.print(pcbs.get(i).getName()+"\t");
for(int k=0;k<queueList.size();k++){
if(pcbs.get(i).getName().equals(queueList.get(k))){
System.out.print(k-pcbs.get(i).getStartTime());
System.out.print("\t");
break;
}
}
for(int k=queueList.size()-1;k>=0;k--){
if(pcbs.get(i).getName().equals(queueList.get(k))){
System.out.print((k-pcbs.get(i).getStartTime())+1);
System.out.print("\t");
break;
}
}
System.out.println();
}
}
3.時間片演算法:
private static void changeByTime(List<PCB> pcbs) {
List<String> queueList=new ArrayList<>();
List<PCB> oldPcbs=new ArrayList<>();
oldPcbs=pcbs;
Scanner scanner=new Scanner(System.in);
System.out.println("請輸入時間片大小:");
int time=scanner.nextInt();
System.out.println("排程佇列中每秒執行的程序如下:");
for(int i=0;i<allTime;){
PCB current=null;
int k=0;
for(int j=0;j<pcbs.size();j++){
PCB pcb=pcbs.get(j);
if(pcb.getIsOver()==false){
if(pcb.getStartTime()<=i){
if(current==null){
current=pcb;
k=j;
break;
}
}
}
}
pcbs.get(k).decrease();
queueList.add(current.getName());
System.out.print(current.getName());
i++;
int j=1;
for(j=1;j<time;j++){
if(pcbs.get(k).getIsOver()==false){
pcbs.get(k).decrease();
queueList.add(current.getName());
System.out.print(current.getName());
i++;
}
}
if(j==time&&pcbs.get(k).getIsOver()==false){
List<PCB> newPcbs=new ArrayList<>();
for(int n=0;n<pcbs.size();n++){
if(n!=k&&pcbs.get(n).getIsOver()==false){
newPcbs.add(pcbs.get(n));
}
}
newPcbs.add(pcbs.get(k));
pcbs=newPcbs;
}
}
int j=0;
System.out.println("\n 優先演算法甘特圖如下:");
System.out.print("0 "+queueList.get(j)+" ");
for(int i=0;i<queueList.size();i++){
if(!queueList.get(i).equals(queueList.get(j))){
System.out.print(i+" "+queueList.get(i)+" ");
j=i;
}
}
System.out.print(" "+(queueList.size()));
pcbs=oldPcbs;
System.out.println("\n程序名:\t"+"等待時間:\t"+"週轉時間:\t");
for(int i=0;i<pcbs.size();i++){
System.out.print(pcbs.get(i).getName()+"\t");
for(int k=0;k<queueList.size();k++){
if(pcbs.get(i).getName().equals(queueList.get(k))){
System.out.print(k-pcbs.get(i).getStartTime());
System.out.print("\t");
break;
}
}
for(int k=queueList.size()-1;k>=0;k--){
if(pcbs.get(i).getName().equals(queueList.get(k))){
System.out.print((k-pcbs.get(i).getStartTime())+1);
System.out.print("\t");
break;
}
}
System.out.println();
}
}
4段作業優先演算法:
private static void shortTaskFrist(List<PCB> pcbs) {
List<String> queueList=new ArrayList<>();
System.out.println("排程佇列中每秒執行的程序如下:");
for(int i=0;i<allTime;i++){
PCB current=null;
int k=0;
for(int j=0;j<pcbs.size();j++){
PCB pcb=pcbs.get(j);
if(pcb.getIsOver()==false){
if(pcb.getStartTime()<=i){
if(current==null){
current=pcb;
}else{
if (current.getRunTime()>pcb.getRunTime()){
current=pcb;
k=j;
}
}
}
}
}
pcbs.get(k).decrease();
queueList.add(current.getName());
System.out.print(current.getName());
}
int j=0;
System.out.println("\n 優先演算法甘特圖如下:");
System.out.print("0 "+queueList.get(j)+" ");
for(int i=0;i<queueList.size();i++){
if(!queueList.get(i).equals(queueList.get(j))){
System.out.print(i+" "+queueList.get(i)+" ");
j=i;
}
}
System.out.print(" "+(queueList.size()));
System.out.println("\n程序名:\t"+"等待時間:\t"+"週轉時間:\t");
for(int i=0;i<pcbs.size();i++){
System.out.print(pcbs.get(i).getName()+"\t");
for(int k=0;k<queueList.size();k++){
if(pcbs.get(i).getName().equals(queueList.get(k))){
System.out.print(k-pcbs.get(i).getStartTime());
System.out.print("\t");
break;
}
}
for(int k=queueList.size()-1;k>=0;k--){
if(pcbs.get(i).getName().equals(queueList.get(k))){
System.out.print((k-pcbs.get(i).getStartTime())+1);
System.out.print("\t");
break;
}
}
System.out.println();
}
}
5.程序的javabean
import com.alibaba.fastjson.JSONObject;
public class PCB {
private int runTime; //執行時間
private int priority; //優先順序
private String name; //程序名臣
private boolean isOver; //是否執行結束
private int startTime; //開始執行時間
public int getRunTime() {
return runTime;
}
public void setRunTime(int runTime) {
this.runTime = runTime;
}
public int getPriority() {
return priority;
}
public void setPriority(int priority) {
this.priority = priority;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public boolean getIsOver() {
return isOver;
}
public void setIsOver(boolean isOver) {
this.isOver = isOver;
}
public int getStartTime() {
return startTime;
}
public void setStartTime(int startTime) {
this.startTime = startTime;
}
public void Json2Object(JSONObject jsonObject) {
setName(jsonObject.getString("name"));
setStartTime(jsonObject.getInteger("startTime"));
setIsOver(jsonObject.getBooleanValue("isOver"));
setPriority(jsonObject.getIntValue("priority"));
setRunTime(jsonObject.getIntValue("runTime"));
}
public void decrease() {
runTime--;
if(runTime<=0){
isOver=true;
}
}
我在工程中將json轉化成object的時候用到了阿里巴巴的fastjson jar包,當然你們也可以用別的jar包。斑竹自知這個工程還有改進的地方,比如在得到所有時刻點的佇列之後計算響應時間和週轉時間,畫甘特圖等為了重用性封裝成類,還有程序的list用佇列可能更好一點(不過斑竹習慣了用arraylist),有需要的同學可以自己改進。希望批評指正。