用java語言,模擬實現作業系統的銀行家演算法。

馮某r發表於2019-01-06

先來看看我理解的銀行家演算法的程式流程圖:
在這裡插入圖片描述

詳細設計

1.先選用儲存程式和系統資源的資料結構,兩者我都是用連結串列的形式儲存的。(其實系統資源用陣列比較好,因為它基本上都是修改,沒有增加和刪除。)。選用連結串列之後就是建立連結串列類的屬性,系統資源的屬性有名字、系統總資源和可用資源。程式類連結串列的屬性是程式名字、最大需要資源的連結串列頭節點和當前佔有資源的連結串列頭節點。
2.然後是設計選單。
在這裡插入圖片描述
大概設計成這樣就行,然後用switch語句執行每一個選項的方法。
前四個選項的輸入,主要就是初始化所有屬性,給屬性賦值就行了。
第七個選項,也是遍歷兩個連結串列,檢視屬性就行了。我重點說一下,5和6的兩個演算法。
3.安全性檢測,因為是檢測,所以進入方法之後,首先賦值程式連結串列和資源的連結串列。然後建立一個判斷當前程式連結串列是否有可以被滿足的程式的方法。傳入程式連結串列的頭節點,如果當前可用資源可以滿足此連結串列的某一個程式節點,就將此節點佔用的資源加到可用資源上。然後刪除此節點,再次呼叫此方法,看是否能滿足某一個節點。如果可用資源數對每一個程式的節點都不滿足,說明當前沒有安全序列。如果每次都能滿足,每次都刪除節點,當頭節點為null的時候,證明所有節點都釋放完畢,安全序列已經生成。
4.開始請求資源,這是銀行家演算法的核心,因為是試分配,所以還是要複製兩條連結串列,然後系統對某一個程式進行資源請求,可以分為五種情況。
①.請求的資源大於系統可用資源,做一個判斷列印一下就可以;
②.請求的資源大於此程式尚需的資源數,做一個判斷列印一下就可以;
③.請求的資源滿足條件,減少系統可用資源,增加請求資源程式的佔有資源,在此狀態下呼叫安全性檢測方法,系統不處於安全狀態。(因為是在複製連結串列中進行的,所以不用再次賦值,直接捨棄複製的連結串列)
④.請求的資源滿足條件,減少系統可用資源,增加請求資源程式的佔有資源,在此狀態下呼叫安全性檢測方法,系統處於安全狀態,系統資源進行真實分配,將複製連結串列的值,賦給真實連結串列。
⑤.系統資源請求加上程式之前所佔有的資源,剛好每種資源等於它的最大需求量,此程式得到滿足,釋放所有資源,將可用資源增加,此程式在真實連結串列中被刪除。

原始碼如下:

import java.util.Scanner;

class Resource{
    String name;
    int num;
    int Available;
    Resource rNext;
    public Resource(String name,int num){
        this.name = name;
        this.num = num;
    }
}


class Process{
    String name;
    Resource maxNeed;
    Resource already;
    Process pNext;
    public Process(String name){
        this.name = name;
    }
}


public class 測試3{
    static int T = 0;  //用來控制檢測安全序列的變數

    //輸入資源的種類和數量
    static void Alloctionadd(Resource res,Process pro){
        Resource cur = res;
        int i = 1;
        while(cur!=null){
            Process tmp = pro;
            int count = 0;
            while(tmp!=null){
                Resource tmp2 = tmp.already;
                for(int j=1; j<i; j++){
                    tmp2 = tmp2.rNext;
                }
                count += tmp2.num;
                tmp = tmp.pNext;
            }
            cur.Available = cur.num-count;
            cur = cur.rNext;
            i++;
        }
    }
    static Resource addResource(Resource res,String str,int num){
        if(res == null){
            res = new Resource(str,num);
            return res;
        }
        Resource cur = res;
        while(cur.rNext!=null){
            cur = cur.rNext;
        }
        cur.rNext = new Resource(str,num);
        return res;
    }
    static Resource InitResource(){
        Resource res = null;
        Scanner sc = new Scanner(System.in);
        System.out.println("資源的數量為:");
        int a=sc.nextInt();
        for(int i=1; i<=a; i++){
            System.out.println("第"+i+"個資源的名稱是:");
            String b=sc.next();
            System.out.println("第"+i+"個資源的資源總數是:");
            int c=sc.nextInt();
            res = addResource(res,b,c);
        }
        return res;
    }

    //輸入程式的數量
    static Process addProcess(Process pro,String str){
        if(pro == null){
            pro = new Process(str);
            return pro;
        }
        Process cur = pro;
        while(cur.pNext!=null){
            cur = cur.pNext;
        }
        cur.pNext = new Process(str);
        return pro;
    }
    static Process InitProcess(int num){
        Process pro = null;
        for(int i=1; i<=num; i++){
            pro = addProcess(pro,"S"+i);
        }
        return pro;
    }


    //程式最大需求資源個數
    static void MaxNeed(Process pro,Resource res){
        Scanner sc = new Scanner(System.in);
        Resource cur2 = null;
        Process cur = pro;
        while(cur!=null){
            int i = 1;
            cur2 = res;
            while(cur2!=null){
                System.out.println(cur.name+"程式的第"+i+"個資源的最大需求量是:");
                int num = sc.nextInt();
                cur.maxNeed = addResource(cur.maxNeed,cur2.name,num);
                cur2 = cur2.rNext;
                i++;
            }
            cur = cur.pNext;
        }
    }
    //t0時刻已經分配的資源
    static void Already(Process pro,Resource res){
        Scanner sc = new Scanner(System.in);
        Resource cur2 = null;
        Process cur = pro;
        while(cur!=null){
            int i = 1;
            cur2 = res;
            while(cur2!=null){
                System.out.println(cur.name+"程式的第"+i+"個資源的已經分配量是:");
                int num = sc.nextInt();
                cur.already = addResource(cur.already,cur2.name,num);
                cur2 = cur2.rNext;
                i++;
            }
            cur = cur.pNext;
        }
    }
    //安全性檢測
    static Process copyProcess(Process pro){
        Process pro2 = null;
        Process cur = pro;
        while(cur!=null){
            pro2 = addProcess(pro2,cur.name);
            cur = cur.pNext;
        }
        Process cur2 = pro2;
        cur = pro;
        while(cur!=null){
            cur2.already = copyResource(cur.already,pro2);
            cur2.maxNeed = copyResource(cur.maxNeed,pro2);
            cur2 = cur2.pNext;
            cur = cur.pNext;
        }
        return pro2;
    }
    static Resource copyResource(Resource res,Process pro){
        Resource res2 = null;
        Resource cur = res;
        while(cur!=null){
            res2 = addResource(res2,cur.name,cur.num);
            cur = cur.rNext;
        }
        cur = res;
        Resource cur2 = res2;
        while(cur!=null){
            cur2.Available = cur.Available;
            cur = cur.rNext;
            cur2 = cur2.rNext;
        }
        return res2;
    }
    static Process IsSecurity(Process pro,Resource res){
        Process cur1 = pro;
        Process pre = cur1;
        Resource cur2 = null;
        while(cur1!=null){
            Resource tmp1 = cur1.maxNeed;
            Resource tmp2 = cur1.already;
            cur2 = res;
            while(cur2!=null){
                if(cur2.Available < tmp1.num - tmp2.num){ // 可用資源是否小於 需要資源
                    break;
                }
                tmp1 = tmp1.rNext;
                tmp2 = tmp2.rNext;
                cur2 = cur2.rNext;
            }
            if(cur2 == null){  //走完了所有資源 都滿足需求
                cur2 = res;
                tmp2 = cur1.already;
                while(cur2!=null){
                    cur2.Available += tmp2.num;
                    cur2 = cur2.rNext;
                    tmp2 = tmp2.rNext;
                }
                System.out.println(cur1.name);
                return pre;
            }
            pre = cur1;
            cur1 = cur1.pNext;
            T++;
        }
        return null;
    }
    static int SecurityCheck(Process pro,Resource res){
        Process pro2 = copyProcess(pro);
        Resource res2 = copyResource(res,pro2);
        while(pro2!=null) {
            T = 0;
            Process pre = IsSecurity(pro2, res2);
            if(pre == null){
                System.out.println("沒有安全序列!!");
                return 0;
            }
            if(pre == pro2 && T == 0){  //T如果沒+過  說明返回的是頭節點
                pro2 = pro2.pNext;
                continue;
            }
            pre.pNext = pre.pNext.pNext;
        }
        return 1;
    }
    //開始請求資源
    static int NewRequires(Process pro,Resource res){
        int count = 0;
        Scanner sc = new Scanner(System.in);
        Process pro2 = copyProcess(pro);
        Resource res2 = copyResource(res,pro2);
        Resource tmp = res2;
        System.out.println("第幾個程式需要請求資源?");
        int a=sc.nextInt();
        Process cur = pro2;
        for(int i=1; i<a; i++){
            cur = cur.pNext;
        }
        Resource cur2 = cur.already;
        Resource max = cur.maxNeed;
        for(int j=1; cur2!=null; j++){
            System.out.println("請輸入第"+j+"個資源新請求的個數:");
            int b=sc.nextInt();
            cur2.num += b;
            if(cur2.num > max.num){
                System.out.println("請求超出最大資源需求,請求出錯!");
                return 0;
            }
            tmp.Available -= b;
            if(tmp.Available < 0){
                System.out.println("已有資源"+tmp.name+"不足,請求錯誤!");
                return 0;
            }
            max = max.rNext;
            tmp = tmp.rNext;
            cur2 = cur2.rNext;
        }
        Resource cur3 = res;
        cur = pro;
        Process cur1 = pro2;
        Process pre = null;
        for(int i=1; i<a; i++){
            pre = cur;
            cur = cur.pNext;
            cur1 = cur1.pNext;
        }
        Resource cur4 = cur.already;

        if(SecurityCheck(pro2,res2) == 1) {
            while (res2 != null) {
                cur3.Available = res2.Available;
                cur4.num = cur1.already.num;
                if(cur4.num != cur1.maxNeed.num){
                    count = 1;
                }
                cur3 = cur3.rNext;
                res2 = res2.rNext;
                cur4 = cur4.rNext;
                cur1.already = cur1.already.rNext;
                cur1.maxNeed = cur1.maxNeed.rNext;
            }
            if(count == 0){
                cur3 = res;
                cur4 = cur.already;
                while(cur3!=null){
                    cur3.Available += cur4.num;
                    cur3 = cur3.rNext;
                    cur4 = cur4.rNext;
                }
                if(pre == null){
                    return 1;
                }else{
                    pre.pNext = pre.pNext.pNext;
                }
            }
        }
        return 0;
    }

    //檢視程式和資源
    static void check(Resource res,Process pro){
        Resource cur = res;
        Process cur2 = pro;
        System.out.println("系統每個資源的總數: "+" 可用資源數");
        while(cur!=null){
            System.out.println(cur.name+" : "+cur.num+"、"+cur.Available);
            cur = cur.rNext;
        }
        System.out.println("系統每個程式的資訊:");
        while(cur2!=null){
            System.out.print(cur2.name+" : ");
            Resource cur3 = cur2.maxNeed;
            System.out.print("各資源最大需求數 :");
            while(cur3!=null){
                System.out.print(cur3.num+"、");
                cur3 = cur3.rNext;
            }
            System.out.print("  各資源當前擁有數 :");
            cur3 = cur2.already;
            while(cur3 !=null){
                System.out.print(cur3.num+"、");
                cur3 = cur3.rNext;
            }
            cur2 = cur2.pNext;
            System.out.println();
        }
    }

    static void menu(){
        Scanner sc = new Scanner(System.in);
        Resource res = null;
        Process pro = null;
        int a = 1;
        while(a!=0)
        {
            System.out.println("1.輸入資源的種類和數量");
            System.out.println("2.輸入程式的數量");
            System.out.println("3.輸入每個程式的最大需求個數");
            System.out.println("4.輸入t0時刻每個程式已經分配的資源個數");
            System.out.println("5.安全性檢測");
            System.out.println("6.開始請求資源");
            System.out.println("7.檢視當前系統的資源和程式");
            System.out.println("0.退出程式");
            System.out.println("請輸入您需要的服務:");
            a=sc.nextInt();
            switch(a){
                case 1:
                    res = InitResource();
                    break;
                case 2:
                    System.out.println("程式的總個數為:");
                    int num = sc.nextInt();
                    pro = InitProcess(num);
                    break;
                case 3:
                    MaxNeed(pro,res);
                    break;
                case 4:
                    Already(pro,res);
                    Alloctionadd(res,pro);
                    break;
                case 5:
                    SecurityCheck(pro,res);
                    break;
                case 6:
                    if(NewRequires(pro,res) == 1){
                        pro = pro.pNext;
                    }
                    break;
                case 7:
                    check(res,pro);
                    break;
                case 0:
                    System.out.println("正常退出!");
                    break;
                default:
                    System.out.println("輸入錯誤,請重新輸入");
                    break;
            }
        }
    }

    public static void main(String[] args) {
        menu();
    }
}

相關文章