【Java學習筆記】45:優先順序佇列PriorityQueue和比較器Comparator
阿新 • • 發佈:2019-01-07
模擬程序排程時的優先數法和簡單時間片輪轉法,前者可以為程序設定以優先數PRIORITY為優先順序,為了更好地併發,每次獲得處理機後優先數減少3而重新選取。
在簡單輪轉法中則僅僅是一個普通佇列,按照FIFO的方式出隊獲得處理機。
如果要使用比較器Comparator給優先順序佇列,在建立時就應作為引數傳入進去。Comparator通過覆寫返回int值的正負來做判斷,常使用匿名內部類。
Main.java
import java.util.Scanner;
//主類
public class Main {
static int proNUM=5;//程序數目
public static void main(String[] args) {
System.out.println("請輸入priority(優先數法)或者RR(輪轉法):");
//從鍵盤讀入字串
Scanner s=new Scanner(System.in);
String str=null;
str=s.next();
//比較
if(true==str.equals("priority"))//使用優先數法
new fun_priority();
else if(true ==str.equals("RR"))//使用簡單輪轉法
new fun_myRR();
else//輸的不對
System.out.println("錯誤的輸入!再見!");
}
}
PCB.java
//程序控制塊
class PCB {
int PID;//程序識別符號
int PRIORITY;//程序優先順序
int CPUTIME;//佔用CPU時間片數
int ALLTIME;//還需時間片數
boolean STATE;//剛剛程序的狀態(有無獲得處理機)
//構造器(初始化)
PCB(int i){
PID=i;
//(資料型別)(最小值+Math.random()*(最大值-最小值+1))
PRIORITY=(int)(1+Math.random()*(60-1+1));
CPUTIME=0;
ALLTIME=(int)(1+Math.random()*(4-1+1));
STATE=false;//阻塞
}
}
fun_priority.java
import java.util.Comparator;
import java.util.PriorityQueue;
import java.util.Queue;
//優先數法
class fun_priority {
static PCB[] pcb=null;//PCB陣列
//有關PCB優先順序,用下標i和j的匿名比較器
public static Comparator<Integer> PriCmp = new Comparator<Integer>(){
@Override
public int compare(Integer i, Integer j) {
return -(pcb[i].PRIORITY-pcb[j].PRIORITY);//這樣優先順序佇列中是大的先出
}
};
//顯示PCB陣列的內容
void display(){
System.out.println("=================================================");
System.out.println("PID PRIORITY CPUTIME ALLTIME (Last Time)STATE");
for(int i=0;i<Main.proNUM;i++)
{
System.out.print(pcb[i].PID+" "+pcb[i].PRIORITY+" "+
pcb[i].CPUTIME+" "+pcb[i].ALLTIME+" "+pcb[i].STATE);
if(pcb[i].ALLTIME==0)
System.out.print(" 已死");
System.out.println("");
}
}
//優先數法的構造器
fun_priority(){
//分配陣列空間
pcb=new PCB[Main.proNUM];
//建立空的優先順序佇列,指定使用PriCmp作為比較器
Queue<Integer> myPriQ= new PriorityQueue<Integer>(Main.proNUM,PriCmp);
//初始化PCB,同時把下標扔進優先順序佇列
for(int i=0;i<Main.proNUM;i++)
{
pcb[i]=new PCB(i);
myPriQ.add(new Integer(i));
}
display();//顯示(初始情況)
Integer index;//臨時用
//迴圈做優先數法
while(false==myPriQ.isEmpty()){
index=myPriQ.poll();//取一個
//優先順序縮減
if(pcb[index].PRIORITY>3)
pcb[index].PRIORITY-=3;
else
pcb[index].PRIORITY=0;
//執行時間縮減,已執行時間增加
pcb[index].ALLTIME-=1;
pcb[index].CPUTIME+=1;
if(pcb[index].ALLTIME>0)//如果還沒執行完
myPriQ.add(index);//再放回去
pcb[index].STATE=true;//先設為true
display();//顯示(每次變化)
pcb[index].STATE=false;//顯示完設回false
}
}
}
fun_myRR.java
import java.util.LinkedList;
import java.util.Queue;
//簡單輪轉法
class fun_myRR {
static PCB[] pcb=null;//PCB陣列
//顯示PCB陣列的內容
void display(){
System.out.println("===========================================================");
System.out.println("PID (無意義的)PRIORITY CPUTIME ALLTIME (Last Time)STATE");
for(int i=0;i<Main.proNUM;i++)
{
System.out.print(pcb[i].PID+" "+pcb[i].PRIORITY+" "+
pcb[i].CPUTIME+" "+pcb[i].ALLTIME+" "+pcb[i].STATE);
if(pcb[i].ALLTIME==0)
System.out.print(" 已死");
System.out.println("");
}
}
//構造器
fun_myRR(){
//分配陣列空間
pcb=new PCB[Main.proNUM];
//建立空的佇列(LinkedList類實現了Queue介面)
Queue<Integer> myQ=new LinkedList<Integer>();
//初始化PCB,同時把下標扔進佇列
for(int i=0;i<Main.proNUM;i++)
{
pcb[i]=new PCB(i);
myQ.add(new Integer(i));
}
display();//顯示(初始情況)
Integer index;//臨時用
//迴圈做RR法
while(false==myQ.isEmpty()){
index=myQ.poll();//取一個
//執行時間縮減,已執行時間增加,這裡時間片設為2
int k=pcb[index].ALLTIME>=2 ? 2 : 1;//這次用掉的時間片
pcb[index].ALLTIME-=k;
pcb[index].CPUTIME+=k;
if(pcb[index].ALLTIME>0)//如果還沒執行完
myQ.add(index);//再放回去
pcb[index].STATE=true;//先設為true
display();//顯示(每次變化)
pcb[index].STATE=false;//顯示完設回false
}
}
}
執行結果1
請輸入priority(優先數法)或者RR(輪轉法):
priority
=================================================
PID PRIORITY CPUTIME ALLTIME (Last Time)STATE
0 9 0 2 false
1 35 0 3 false
2 9 0 4 false
3 13 0 4 false
4 20 0 4 false
=================================================
PID PRIORITY CPUTIME ALLTIME (Last Time)STATE
0 9 0 2 false
1 32 1 2 true
2 9 0 4 false
3 13 0 4 false
4 20 0 4 false
=================================================
PID PRIORITY CPUTIME ALLTIME (Last Time)STATE
0 9 0 2 false
1 29 2 1 true
2 9 0 4 false
3 13 0 4 false
4 20 0 4 false
=================================================
PID PRIORITY CPUTIME ALLTIME (Last Time)STATE
0 9 0 2 false
1 26 3 0 true 已死
2 9 0 4 false
3 13 0 4 false
4 20 0 4 false
=================================================
PID PRIORITY CPUTIME ALLTIME (Last Time)STATE
0 9 0 2 false
1 26 3 0 false 已死
2 9 0 4 false
3 13 0 4 false
4 17 1 3 true
=================================================
PID PRIORITY CPUTIME ALLTIME (Last Time)STATE
0 9 0 2 false
1 26 3 0 false 已死
2 9 0 4 false
3 13 0 4 false
4 14 2 2 true
=================================================
PID PRIORITY CPUTIME ALLTIME (Last Time)STATE
0 9 0 2 false
1 26 3 0 false 已死
2 9 0 4 false
3 13 0 4 false
4 11 3 1 true
=================================================
PID PRIORITY CPUTIME ALLTIME (Last Time)STATE
0 9 0 2 false
1 26 3 0 false 已死
2 9 0 4 false
3 10 1 3 true
4 11 3 1 false
=================================================
PID PRIORITY CPUTIME ALLTIME (Last Time)STATE
0 9 0 2 false
1 26 3 0 false 已死
2 9 0 4 false
3 10 1 3 false
4 8 4 0 true 已死
=================================================
PID PRIORITY CPUTIME ALLTIME (Last Time)STATE
0 9 0 2 false
1 26 3 0 false 已死
2 9 0 4 false
3 7 2 2 true
4 8 4 0 false 已死
=================================================
PID PRIORITY CPUTIME ALLTIME (Last Time)STATE
0 9 0 2 false
1 26 3 0 false 已死
2 6 1 3 true
3 7 2 2 false
4 8 4 0 false 已死
=================================================
PID PRIORITY CPUTIME ALLTIME (Last Time)STATE
0 6 1 1 true
1 26 3 0 false 已死
2 6 1 3 false
3 7 2 2 false
4 8 4 0 false 已死
=================================================
PID PRIORITY CPUTIME ALLTIME (Last Time)STATE
0 6 1 1 false
1 26 3 0 false 已死
2 6 1 3 false
3 4 3 1 true
4 8 4 0 false 已死
=================================================
PID PRIORITY CPUTIME ALLTIME (Last Time)STATE
0 3 2 0 true 已死
1 26 3 0 false 已死
2 6 1 3 false
3 4 3 1 false
4 8 4 0 false 已死
=================================================
PID PRIORITY CPUTIME ALLTIME (Last Time)STATE
0 3 2 0 false 已死
1 26 3 0 false 已死
2 3 2 2 true
3 4 3 1 false
4 8 4 0 false 已死
=================================================
PID PRIORITY CPUTIME ALLTIME (Last Time)STATE
0 3 2 0 false 已死
1 26 3 0 false 已死
2 3 2 2 false
3 1 4 0 true 已死
4 8 4 0 false 已死
=================================================
PID PRIORITY CPUTIME ALLTIME (Last Time)STATE
0 3 2 0 false 已死
1 26 3 0 false 已死
2 0 3 1 true
3 1 4 0 false 已死
4 8 4 0 false 已死
=================================================
PID PRIORITY CPUTIME ALLTIME (Last Time)STATE
0 3 2 0 false 已死
1 26 3 0 false 已死
2 0 4 0 true 已死
3 1 4 0 false 已死
4 8 4 0 false 已死
執行結果2
請輸入priority(優先數法)或者RR(輪轉法):
RR
===========================================================
PID (無意義的)PRIORITY CPUTIME ALLTIME (Last Time)STATE
0 25 0 2 false
1 42 0 4 false
2 33 0 1 false
3 7 0 3 false
4 60 0 3 false
===========================================================
PID (無意義的)PRIORITY CPUTIME ALLTIME (Last Time)STATE
0 25 2 0 true 已死
1 42 0 4 false
2 33 0 1 false
3 7 0 3 false
4 60 0 3 false
===========================================================
PID (無意義的)PRIORITY CPUTIME ALLTIME (Last Time)STATE
0 25 2 0 false 已死
1 42 2 2 true
2 33 0 1 false
3 7 0 3 false
4 60 0 3 false
===========================================================
PID (無意義的)PRIORITY CPUTIME ALLTIME (Last Time)STATE
0 25 2 0 false 已死
1 42 2 2 false
2 33 1 0 true 已死
3 7 0 3 false
4 60 0 3 false
===========================================================
PID (無意義的)PRIORITY CPUTIME ALLTIME (Last Time)STATE
0 25 2 0 false 已死
1 42 2 2 false
2 33 1 0 false 已死
3 7 2 1 true
4 60 0 3 false
===========================================================
PID (無意義的)PRIORITY CPUTIME ALLTIME (Last Time)STATE
0 25 2 0 false 已死
1 42 2 2 false
2 33 1 0 false 已死
3 7 2 1 false
4 60 2 1 true
===========================================================
PID (無意義的)PRIORITY CPUTIME ALLTIME (Last Time)STATE
0 25 2 0 false 已死
1 42 4 0 true 已死
2 33 1 0 false 已死
3 7 2 1 false
4 60 2 1 false
===========================================================
PID (無意義的)PRIORITY CPUTIME ALLTIME (Last Time)STATE
0 25 2 0 false 已死
1 42 4 0 false 已死
2 33 1 0 false 已死
3 7 3 0 true 已死
4 60 2 1 false
===========================================================
PID (無意義的)PRIORITY CPUTIME ALLTIME (Last Time)STATE
0 25 2 0 false 已死
1 42 4 0 false 已死
2 33 1 0 false 已死
3 7 3 0 false 已死
4 60 3 0 true 已死