1. 程式人生 > >【Java學習筆記】45:優先順序佇列PriorityQueue和比較器Comparator

【Java學習筆記】45:優先順序佇列PriorityQueue和比較器Comparator

模擬程序排程時的優先數法簡單時間片輪轉法,前者可以為程序設定以優先數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 已死