銀行家算法(預先知道系統資源需求合理分配預防死鎖)

 

銀行家算法

<代碼實現>

import java.util.Arrays;

public class Banker {

    public static int[]   available  =   {3 , 3 ,2};    //系統資源剩餘個數
    public static int[][] allocation = { {0 , 1 , 0},   //系統已分配給各個進程的資源情況
                                           {2 , 0 , 0},
                                           {3 , 0 , 2},
                                           {2 , 1 , 1},
                                           {0 , 0 , 2}
                                          };
    public static int[][] need       =  { {7 , 4 , 3},  //系統個進程還需要的資源情況 
                                            {1 , 2 , 2},
                                            {6 , 0 , 0},
                                            {0 , 1 , 1},
                                            {4 , 3 , 1}
                                           };
    //public static int[][] max       = new int[6][6];


    //資源請求(成功請求 返回1 否則未通過安全測試 返回-1)
    public static int reqSource(
              int who           //哪個進程
            , int[] more        //申請資源數
            , int[][] allocation//系統已經分配資源數目
            , int[] available   //系統剩餘資源數目
            , int[][] need      //各個進程還需要的資源數
            , int n             //系統進程總數目
            , int typeN){       //資源類型數目
        //將系統資源使用圖(數組)備份一份
        int[]   work    = Arrays.copyOf(available,typeN);
        int[][] alloc   = new int[n][typeN];
        int[][] tmpNeed = new int[n][typeN];
        copyTOf(allocation,alloc);
        copyTOf(need,tmpNeed);

        //printO(work);
        //printT(alloc);
        //printT(tmpNeed);

        if(compare(more , work , typeN)){                    //檢測是否有足夠的資源
            alloc[who]   = addArray(alloc[who],more,typeN);  //通過檢測將備份的資源使用情況更新
            tmpNeed[who] = minusArray(tmpNeed[who],more,typeN);
            work         = minusArray(work,more,typeN);

            //printO(alloc[who]);
            //printO(tmpNeed[who]);
            //printO(work);

            if(safeTest(work ,alloc , tmpNeed , n ,typeN)){        //將資源分配個其後檢測是否通過安全測試
                allocation[who] = Arrays.copyOf(alloc[who],typeN); //安全測試通過後將實際資源分配給他並且將更新實際的資源使用情況
                need[who]       = Arrays.copyOf(tmpNeed[who],typeN);
                available       = Arrays.copyOf(work,typeN);
                return 1;
            }
        }
        return -1;
    }

    //安全測試 (參數 : 1系統剩餘資源數 2已分配給進程資源數 3還需要的資源數 4總進程數 4總資源類型數)
    public static boolean safeTest(int[] available,int[][] allocation,int[][] need , int n ,int typeN){
        int[] finish = new int[n];
        int[] work   = Arrays.copyOf(available,typeN);
        int[] pOrder = new int[n];  //用於存儲最後資源的使用順序如果通過安全測試將其打印

        for(int x = 0 ; x < n ; x++)
            finish[x] = 0;

        //O(n * (typeN + typeN + n! * (typeN + typeN))) = O(n*typeN + n*n!*typeN) = O(n*typeN*(1+n!))
        for(int i = 0;i < n;  i++){
            if(compare(need[i],work,typeN)){   //可以從第i項開始檢測
                work = addArray(work,allocation[i],typeN);
                //printO(work);
                finish[i] = 1;
                int j = (i + 1)%n;
                int count = 1; //用於記錄已分配資源進程數
                pOrder[count-1] = i;
                while (true){
                   if(finish[j] != 1&&compare(need[j],work,typeN)){
                       work = addArray(work,allocation[j],typeN);
                       //printO(work);
                       finish[j] = 1;
                       count++;
                       pOrder[count-1] = j;
                       j = (i + 1)%n;
                   }else {
                       j = (j + 1)%n;
                       if(j == i && count != n){
                           /*for(int x = 0 ; x < n ; x++)
                               finish[x] = 0;
                           break;*/
                           return false;
                       }
                       else if(j == i && count == n) {
                           System.out.print("pOrder : < ");
                           for(int k = 0 ; k < n ; k++){
                               System.out.print("p" + pOrder[k] + ", ");
                           }
                           System.out.println(">");
                           return true;
                       }
                   }
                }
            }
        }
        return false;
    }

    /**
     * 輔助方法
     */

    //比較兩個數組大小(如果a1的每一項都比a2小 返回true 否則 false)
    public static boolean compare(int[] a1 , int[] a2 , int n){
        for(int i = 0 ; i < n ; i++){
            if(a1[i] > a2[i])
                return false;
        }
        return true;
    }

    //數組元素求和
    public static  int[] addArray(int[] a1 , int[] a2 , int n){
        int[] tmp = new int[n];
        for(int i = 0 ; i < n ; i++){
            tmp[i] = a1[i] + a2[i];
        }
        return tmp;
    }

    //數組元素相減
    public static int[] minusArray(int[] a1 , int[] a2 , int n){
        int[] tmp = new int[n];
        for(int i = 0 ; i < n ; i++){
            tmp[i] = a1[i] - a2[i];
        }
        return tmp;
    }

    //二維數組複製
    public static void copyTOf(int[][] a1 , int[][] a2){
        for(int i = 0 ; i < a1.length ; i++){
            for(int j = 0 ; j < a1[i].length ; j++){
                a2[i][j] = a1[i][j];
            }
        }
    }

    public static void printO(int[] a){
        System.out.print("" + a.toString());
        for(int tmp : a){
            System.out.print(" " + tmp);
        }
        System.out.println();
    }

    public static void printT(int[][] a){
        System.out.println("" + a.toString());
        for(int[] a1 : a){
            for(int a2 : a1){
                System.out.print(" " + a2);
            }
            System.out.println();
        }
    }


    public static void main(String[] args){
        //safeTest(available,allocation,need,5,3);

        int[] more = {3,3,0};
        if(reqSource(4,more,allocation,available,need,5,3) == 1){
            System.out.println("safe!");
        }else{
            System.out.println("non safe!");
        }
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章