銀行家算法java版

銀行家算法是用來避免死鎖的。

我自己的理解:我(銀行家)手裏有一筆資金,我現在要把這筆自己借出去,現在我需要保證,我以適當的順序去借出這筆存款,能保證我可以供給所有的借款者。即有一個安全序列(我借出去之後,它在有限時間內歸還給我,我就可以再次將這筆錢借給另外一個人。)

但是,如果我預測找不到這樣一個序列,也就是說,我不能同時滿足當前系統所有人的借款需求,即系統處於不安全的狀態!

 

首先我們定義幾個矩陣,矩陣功能見代碼

 /**
     * 系統資源種類數
     * */
    private int sourceKinds;
    /**
     * 系統進程數目
     * */
    private int threadNums;

    /**
     * 初始資源數量
     * */
    private int source[];
    /**
     * 線程需要的最大資源數矩陣
     * */
    private int[][] MAX ;
    /**
     * 已分配給線程的資源矩陣
     * */
    private int[][] Allocation ;
    /**
     * 需求矩陣
     * */
    private int[][] Need;
    /**
     * 資源剩餘矩陣
     * */
    private int[] Available;
    /**
     * 系統可提供給進程繼續運行所需的各類資源數目
     * */
    private int[]Work;

然後我們就可以實現這個銀行家算法了。

全部代碼如下

package com.ly;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;

/**
 * Created by BorisLiu on 2019/10/21
 */
public class Banker {

    /**
     * 系統資源種類數
     * */
    private int sourceKinds;
    /**
     * 系統進程數目
     * */
    private int threadNums;

    /**
     * 初始資源數量
     * */
    private int source[];
    /**
     * 線程需要的最大資源數矩陣
     * */
    private int[][] MAX ;
    /**
     * 已分配給線程的資源矩陣
     * */
    private int[][] Allocation ;
    /**
     * 需求矩陣
     * */
    private int[][] Need;
    /**
     * 資源剩餘矩陣
     * */
    private int[] Available;
    /**
     * 系統可提供給進程繼續運行所需的各類資源數目
     * */
    private int[]Work;

    public Banker(int threadNums,int sourceKinds,int source[]){
        this.threadNums = threadNums;
        this.sourceKinds = sourceKinds;
        this.source = source;
        this.MAX = new int[threadNums][sourceKinds];
        this.Allocation = new int[threadNums][sourceKinds];
        this.Need = new int[threadNums][sourceKinds];
        for (int i = 0; i < threadNums; i++) {
           this.MAX[i] = new int[sourceKinds];
           this.Allocation[i] = new int[sourceKinds];
           this.Need[i] = new int[sourceKinds];
        }

        Available = new int[sourceKinds];
        Work = new int[sourceKinds];
    }
    /**
     * 設置進程需要最大資源數
     * */
    public void setMAX(){
        Scanner in = new Scanner(System.in);
        for (int i = 0; i < threadNums; i++) {
            System.out.println("請輸入進程"+i+"最大需要的資源數目:");
            for (int j = 0; j < sourceKinds; j++) {
                System.out.println("請輸入需要資源"+j+"的數目:");
                MAX[i][j] = in.nextInt();
            }
        }

//        for (int i = 0; i < threadNums; i++) {
//            for (int j = 0; j < sourceKinds; j++) {
//                System.out.print(MAX[i][j]+"==》");
//            }
//            System.out.println();
//        }
    }
    /**
     * 設置初始已分配資源
     * */
    public void setAllocation(){
        Scanner in = new Scanner(System.in);
        for (int i = 0; i < threadNums; i++) {
            System.out.println("請輸入進程"+i+"初始已分配資源數目:");
            for (int j = 0; j < sourceKinds; j++) {
                System.out.println("請輸入進程"+i+"初始已分類資源"+j+"的數目:");
                Allocation[i][j] = in.nextInt();
            }
        }
    }

    private void setNeed(){
        /**
         * 計算need矩陣
         * */
        for (int i = 0; i < threadNums; i++) {
            for (int j = 0; j < sourceKinds; j++) {
                Need[i][j] = MAX[i][j] - Allocation[i][j];
            }
        }
        /**
         * 計算剩餘資源矩陣
         * */
        for (int i = 0; i < sourceKinds; i++) {
            int sum = 0;
            for (int j = 0; j < threadNums; j++) {
                sum+=Allocation[j][i];
            }
            Available[i] = source[i] - sum;
        }
    }

    /**
     * 找到一個安全序列
     * */
    private void findSafeSequence(){
        System.arraycopy(Available,0,Work,0,Available.length);

        int[] preWork = new int[Work.length];
        System.arraycopy(Available,0,preWork,0,Available.length);

        boolean Finish[] = new boolean[threadNums];
        List<String>  result = new ArrayList<String>();
        boolean flag = true;

        while(flag){
            boolean bool = false;
            for (int i = 0; i < threadNums; i++) {
                int count = 0;
                // 統計是否need【i】都 <= work[j]
                for (int j = 0; j < sourceKinds; j++ ) {
                    if (Need[i][j]<=Work[j]&&(!Finish[i])){
                        count++;
                    }
                }
                /**
                 * 如果need <= work
                 * */
                if (count == sourceKinds && (!Finish[i])){
                    for (int j = 0; j < sourceKinds; j++) {
                        Work[j] += Allocation[i][j];
                        Finish[i] = true;
                    }
                    result.add("P"+i);
                    bool = true;
                    break;
                }

            }
            if (bool){
                for (int i = 0; i < sourceKinds; i++) {
                    System.out.print("選擇前work==>"+preWork[i]);
                    System.out.print("選擇後work==>"+Work[i]);
                    System.out.println();
                }
                //更新preWork
                for (int i = 0; i < Work.length; i++) {
                    preWork[i] = Work[i];
                }

                flag = true;
            }else {
                flag = false;
            }

        }


        for (int i = 0; i < Available.length; i++) {
            System.out.print(Work[i]+"====");
        }
        System.out.println();

        if (result.size() == threadNums){
            System.out.println("找到安全序列!!!");
            result.forEach((e)->{
                System.out.println(e);
            });
        }else{
            System.out.println("沒有找到安全序列!!!");
        }
    }

    public void print(){
        System.out.println("進程 Max Alloction Need Available ");
        for (int i = 0; i < threadNums; i++) {
            System.out.print("P"+i+" ");
            for (int j = 0; j < sourceKinds; j++) {
                System.out.print(MAX[i][j]+" |");
            }
            System.out.println();
        }
        for (int i = 0; i < threadNums; i++) {
            for (int j = 0; j < sourceKinds; j++) {
                System.out.print(Allocation[i][j]+" |");
            }
            System.out.println();
        }
        for (int i = 0; i < threadNums; i++) {
            for (int j = 0; j < sourceKinds; j++) {
                System.out.print(Need[i][j]+" |");
            }
            System.out.println();
        }

        for (int i = 0; i < sourceKinds; i++) {
            System.out.print(Available[i]+" ");
        }
        System.out.println("==>|");
    }


    public void initInput(){
        setMAX();
        setAllocation();
        setNeed();
        findSafeSequence();
    }


    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int threadNums = 0;
        int sourceNums = 0;
        int num = 0;
        System.out.println("請輸入初始資源數:");
        num = in.nextInt();
        int[] source = new int[num];
        for (int i = 0; i < num; i++) {
            source[i] = in.nextInt();
        }
        System.out.println("請輸入進程數==>");
        threadNums = in.nextInt();
        System.out.println("請輸入資源種類數==>");
        sourceNums = in.nextInt();

        Banker banker = new Banker(threadNums,sourceNums,source);
        banker.initInput();

    }





}

 

輸出結果:

請輸入初始資源數:
3
10 8 7
請輸入進程數==>
3
請輸入資源種類數==>
3
請輸入進程0最大需要的資源數目:
請輸入需要資源0的數目:
8
請輸入需要資源1的數目:
7
請輸入需要資源2的數目:
5
請輸入進程1最大需要的資源數目:
請輸入需要資源0的數目:
5
請輸入需要資源1的數目:
2
請輸入需要資源2的數目:
5
請輸入進程2最大需要的資源數目:
請輸入需要資源0的數目:
6
請輸入需要資源1的數目:
6
請輸入需要資源2的數目:
2
請輸入進程0初始已分配資源數目:
請輸入進程0初始已分類資源0的數目:
3
請輸入進程0初始已分類資源1的數目:
2
請輸入進程0初始已分類資源2的數目:
0
請輸入進程1初始已分配資源數目:
請輸入進程1初始已分類資源0的數目:
2
請輸入進程1初始已分類資源1的數目:
0
請輸入進程1初始已分類資源2的數目:
2
請輸入進程2初始已分配資源數目:
請輸入進程2初始已分類資源0的數目:
1
請輸入進程2初始已分類資源1的數目:
3
請輸入進程2初始已分類資源2的數目:
2
選擇前work==>4選擇後work==>6
選擇前work==>3選擇後work==>3
選擇前work==>3選擇後work==>5
選擇前work==>6選擇後work==>7
選擇前work==>3選擇後work==>6
選擇前work==>5選擇後work==>7
選擇前work==>7選擇後work==>10
選擇前work==>6選擇後work==>8
選擇前work==>7選擇後work==>7
10====8====7====
找到安全序列!!!
P1
P2
P0

 

 

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