银行家算法---java实现

银行家算法—java实现

看了网上其他代码(java)的实现,总结以下缺陷

1、资源数目和进程数目是固定的。
2、当一个进程请求资源后导致进入不安全状态时,数据没有回滚到请求之前的状态。
3、当一个进程得到全部需要的资源后,没有把他从进程队列中剔除。
4、每次请求应当建立在上次请求的结果之上。

以上缺陷网上代码可能出现一种或多种,满足不了我追求完美的心,哈哈哈,所以我自己写了一个解决了以上所有缺陷。

欢迎白嫖 给个赞就行。

先看运行结果:

运行结果:

输入资源数目
3
输入进程数目
5
请输入Max矩阵
7 5 3
3 2 2
9 0 2
2 2 2
4 3 3
请输入allocation矩阵
0 1 0
2 0 0
3 0 2
2 1 1
0 0 2
输入当前可用资源
3 3 2
    max         allocation          need            avialiable
p0  7 5 3          0 1 0           7 4 3             3 3 2 

p1  3 2 2          2 0 0           1 2 2             

p2  9 0 2          3 0 2           6 0 0             

p3  2 2 2          2 1 1           0 1 1             

p4  4 3 3          0 0 2           4 3 1             

进程     Work     Alloction     Need       Work+Alloction 
P1  3  3  2  |  2  0  0  |  1  2  2  |  5  3  2  
P3  5  3  2  |  2  1  1  |  0  1  1  |  7  4  3  
P4  7  4  3  |  0  0  2  |  4  3  1  |  7  4  5  
P0  7  4  5  |  0  1  0  |  7  4  3  |  7  5  5  
P2  7  5  5  |  3  0  2  |  6  0  0  |  10  5  7  
此时存在一个安全序列:P1 P3 P4 P0 P2 故当前可分配!
    max         allocation          need            avialiable
p0  7 5 3          0 1 0           7 4 3             3 3 2 

p1  3 2 2          2 0 0           1 2 2             

p2  9 0 2          3 0 2           6 0 0             

p3  2 2 2          2 1 1           0 1 1             

p4  4 3 3          0 0 2           4 3 1             

    max         allocation          need            avialiable
p0  7 5 3          0 1 0           7 4 3             3 3 2 

p1  3 2 2          2 0 0           1 2 2             

p2  9 0 2          3 0 2           6 0 0             

p3  2 2 2          2 1 1           0 1 1             

p4  4 3 3          0 0 2           4 3 1             

请输入请求资源的进程编号:
2
请输入请求各资源的数量:
0 0 2
即进程P2对各资源请求Request:(0,0,2).
进程P2请求已经超出最大需求量Need.
您是否还要进行请求:y/n?
y
请输入请求资源的进程编号:
1
请输入请求各资源的数量:
0 0 2
即进程P1对各资源请求Request:(0,0,2).
    max         allocation          need            avialiable
p0  7 5 3          0 1 0           7 4 3             3 3 0 

p1  3 2 2          2 0 2           1 2 0             

p2  9 0 2          3 0 2           6 0 0             

p3  2 2 2          2 1 1           0 1 1             

p4  4 3 3          0 0 2           4 3 1             

现在进入安全算法:
进程     Work     Alloction     Need       Work+Alloction 
P1  3  3  0  |  2  0  2  |  1  2  0  |  5  3  2  
P3  5  3  2  |  2  1  1  |  0  1  1  |  7  4  3  
P4  7  4  3  |  0  0  2  |  4  3  1  |  7  4  5  
P0  7  4  5  |  0  1  0  |  7  4  3  |  7  5  5  
P2  7  5  5  |  3  0  2  |  6  0  0  |  10  5  7  
此时存在一个安全序列:P1 P3 P4 P0 P2 故当前可分配!
    max         allocation          need            avialiable
p0  7 5 3          0 1 0           7 4 3             3 3 0 

p1  3 2 2          2 0 2           1 2 0             

p2  9 0 2          3 0 2           6 0 0             

p3  2 2 2          2 1 1           0 1 1             

p4  4 3 3          0 0 2           4 3 1             

您是否还要进行请求:y/n?
y
请输入请求资源的进程编号:
4
请输入请求各资源的数量:
3 0 0
即进程P4对各资源请求Request:(3,0,0).
    max         allocation          need            avialiable
p0  7 5 3          0 1 0           7 4 3             0 3 0 

p1  3 2 2          2 0 2           1 2 0             

p2  9 0 2          3 0 2           6 0 0             

p3  2 2 2          2 1 1           0 1 1             

p4  4 3 3          3 0 2           1 3 1             

现在进入安全算法:
进程     Work     Alloction     Need       Work+Alloction 
当前系统处于不安全状态,故不存在安全序列 。 
--------恢复数据------ 
    max         allocation          need            avialiable
p0  7 5 3          0 1 0           7 4 3             3 3 0 

p1  3 2 2          2 0 2           1 2 0             

p2  9 0 2          3 0 2           6 0 0             

p3  2 2 2          2 1 1           0 1 1             

p4  4 3 3          0 0 2           4 3 1             

您是否还要进行请求:y/n?
y
请输入请求资源的进程编号:
0
请输入请求各资源的数量:
0 2 0
即进程P0对各资源请求Request:(0,2,0).
    max         allocation          need            avialiable
p0  7 5 3          0 3 0           7 2 3             3 1 0 

p1  3 2 2          2 0 2           1 2 0             

p2  9 0 2          3 0 2           6 0 0             

p3  2 2 2          2 1 1           0 1 1             

p4  4 3 3          0 0 2           4 3 1             

现在进入安全算法:
进程     Work     Alloction     Need       Work+Alloction 
当前系统处于不安全状态,故不存在安全序列 。 
--------恢复数据------ 
    max         allocation          need            avialiable
p0  7 5 3          0 1 0           7 4 3             3 3 0 

p1  3 2 2          2 0 2           1 2 0             

p2  9 0 2          3 0 2           6 0 0             

p3  2 2 2          2 1 1           0 1 1             

p4  4 3 3          0 0 2           4 3 1             

您是否还要进行请求:y/n?

2.代码

代码如下:

package Yinhangjia;

import java.util.Scanner;

/**银行家算法
 * @author hrl
 * @date 2021年04月24日12:57
 */
class Banker {
    int max[][] = new int[100][100];
    int allocation[][] = new int[100][100];
    int need[][] = new int[100][100];
    int avialiable[] = new int[100];
    int request[][] = new int[100][100];
    boolean[] finish = new boolean[100];//进程是否结束
    int work[] = new int[100];

    //资源数目
    int scount ;
    //进程数目;
    int pcount;
    //剩余进程的个数
    int fcount;

    int num = 0;//进程编号
    Scanner in = new Scanner(System.in);

    //数据备份
    int b_allocation[][] = new int[100][100];
    int b_max[][] = new int[100][100];
    int b_avialiable[] = new int[100];
    int b_need[][] = new int[100][100];
    boolean[] b_finish = new boolean[100];
    /*
     * 初始化
     * @author hrl
     * @date 2021/4/24 14:08
     */
    public  void intit(){
        Scanner scanner = new Scanner(System.in);
        System.out.println("输入资源数目");
        scount =scanner.nextInt();
        System.out.println("输入进程数目");
        pcount = scanner.nextInt();
        fcount =pcount;
        System.out.println("请输入Max矩阵");
        for(int i = 0 ; i<pcount; i++) {
            for(int j= 0 ;j < scount; j++) {
                max[i][j]= scanner.nextInt();
            }
        }
        System.out.println("请输入allocation矩阵");
        for(int i = 0 ; i<pcount; i++) {
            for(int j= 0 ;j < scount; j++) {
                allocation[i][j]= scanner.nextInt();
            }
        }
        //计算need[][]
        for(int i = 0 ; i<pcount; i++) {
            for(int j= 0 ;j < scount; j++) {
                need[i][j] = max[i][j] - allocation[i][j];
            }
        }
        System.out.println("输入当前可用资源");
        for(int i = 0 ; i < scount ; i ++) {
            avialiable[i] = scanner.nextInt();
        }
        //初始化finish
        for(int i =0 ; i < pcount; i++) {
            finish[i] = false;
        }
        dispaly();
        SecurityAlgorithm();
    }
    /*
     * 显示资源状况
     * @author hrl
     * @date 2021/4/24 14:25
     * @param null
     * @return null
     */
    public void dispaly () {
        System.out.println("    max         allocation          need            avialiable");
        boolean flag = true;
        for (int i =0; i < pcount; i++ ) {
            if(!finish[i]) {
            System.out.print("p"+i+"  " );
            for (int j = 0; j < scount; j++){
                System.out.print(max[i][j]+" ");
            }
            System.out.print("         ");
            for (int j = 0; j < scount; j++){
                System.out.print(allocation[i][j]+" ");
            }
            System.out.print("          ");
            for (int j = 0; j < scount; j++){
                System.out.print(need[i][j]+" ");
            }
            System.out.print("            ");
            if(flag ){
                for (int j = 0; j < scount; j++){
                    System.out.print(avialiable[j]+" ");
                }
                flag=false;
            }
            System.out.println('\n');
        }
    }
    }


    //判断 请求资源是否超过 需要的资源
    public  boolean eq2Arry(int request[][],int need[][],int num){
        boolean result = true;
        for(int i = 0 ; i < scount;i++) {
            if(request[num][i] > need[num][i]){
                result =false;
                break;
            }
        }
        return result;
    }
    //判断可用资源是否大于 请求资源
    public  boolean eq1Arry(int request[][],int avialiable[],int num) {
        boolean result = true;
        for(int i = 0 ; i < scount; i++) {
            if(request[num][i] > avialiable[i]){
                result= false;
                break;
            }
        }
        return result;
    }

    public void setRequest() {//设置请求资源量Request
        System.out.println("请输入请求资源的进程编号:");
        num= in.nextInt();//设置全局变量进程编号num
        System.out.println("请输入请求各资源的数量:");
        for (int j = 0; j < scount; j++) {
            request[num][j] = in.nextInt();
        }
        System.out.println("即进程P" + num + "对各资源请求Request:(" + request[num][0] + "," + request[num][1] + "," + request[num][2] + ").");

        BankerAlgorithm();
    }

    //备份数据
    public  void save (int ma[][],int all[][],int ava[],boolean rollback){

        //rollback 为真 恢复数据
        if(rollback){
            for(int i = 0; i < pcount; i++ ){
                for(int j = 0 ; j < scount; j++){
                 allocation[i][j] = b_allocation[i][j];
                 max[i][j] = b_max[i][j];
                 need[i][j]= b_need[i][j];
                }
                avialiable[i] = b_avialiable[i];
                finish[i]=b_finish[i];
            }
        }else {
            for(int i = 0; i < pcount; i++ ){
                for(int j = 0 ; j < scount; j++){
                    b_allocation[i][j]    =    allocation[i][j];
                    b_max[i][j]  =   max[i][j]  ;
                    b_need[i][j]  =  need[i][j] ;
                }
                 b_avialiable[i] = avialiable[i] ;
                b_finish[i] = finish[i];
            }
        }

    }

    //判断请求是否合法
    public void BankerAlgorithm() {//银行家算法
        boolean T=true;

        if (eq2Arry(request,need,num)) {//判断Request是否小于Need
            if (eq1Arry(request,avialiable,num)) {//判断Request是否小于Alloction
                //数据备份
                save(max,allocation,avialiable,false);
                for (int i = 0; i < scount; i++) {
                    avialiable[i] -= request[num][i];
                    allocation[num][i] += request[num][i];
                    need[num][i] -= request[num][i];
                }

            } else {
                System.out.println("当前没有足够的资源可分配,进程P" + num + "需等待。");
                T=false;
            }
        } else {
            System.out.println("进程P" + num + "请求已经超出最大需求量Need.");
            T=false;
        }

        if(T==true){
           dispaly();
            System.out.println("现在进入安全算法:");
            SecurityAlgorithm();
        }
    }

    //安全检测
    public void SecurityAlgorithm() {//安全算法
        Boolean Finish[] = new Boolean[100];
        for(int i =0 ; i < pcount; i++) {
            Finish[i] = false;
        }

        int count = 0;//完成进程数
        int circle=0;//循环圈数
        int[] S=new int[100];//安全序列
        for (int i = 0; i < scount; i++) {//设置工作向量
            work[i] = avialiable[i];
        }
        boolean flag = true;
        while (count < fcount) {
            if(flag){
                System.out.println("进程  "+"   Work  "+"   Alloction "+"    Need  "+"     Work+Alloction ");
                flag = false;
            }

            for (int i = 0; i < pcount; i++) {


                if (Finish[i]==false && finish[i] == false && eq1Arry(need,work,i) ) {//判断条件
                    System.out.print("P"+i+"  ");
                    for (int k = 0; k < scount; k++){
                        System.out.print(work[k]+"  ");
                    }
                    System.out.print("|  ");
                    for (int j = 0; j<scount;j++){
                        work[j]+=allocation[i][j];
                    }
                    Finish[i]=true;//当当前进程能满足时


                        S[count]=i;//设置当前序列排号



                    count++;//满足进程数加1
                    for(int j=0;j<scount;j++){
                        System.out.print(allocation[i][j]+"  ");
                    }
                    System.out.print("|  ");
                    for(int j=0;j<scount;j++){
                        System.out.print(need[i][j]+"  ");
                    }
                    System.out.print("|  ");
                    for(int j=0;j<scount;j++){
                        System.out.print(work[j]+"  ");
                    }
                    System.out.println();
                }

            }
            circle++;//循环圈数加1

            if(count==fcount){//判断是否满足所有进程需要
                System.out.print("此时存在一个安全序列:");
                for (int i = 0; i<fcount;i++){//输出安全序列
                    System.out.print("P"+S[i]+" ");
                }
                //保存
                gcS();
                save(max,allocation,avialiable,false);
                System.out.println("故当前可分配!");
                dispaly();
                break;//跳出循环
            }
            if(count<circle){//判断完成进程数是否小于循环圈数
                count=pcount;
                System.out.println("当前系统处于不安全状态,故不存在安全序列 。 ");
                System.out.println("--------恢复数据------ ");
                save(max,allocation,avialiable,true);
                dispaly();
                break;//跳出循环
            }
        }
    }

   // public 资源回收
    public void gcS(){
        for (int i = 0 ; i < pcount ; i++) {
            int index ;
            boolean flag = true;
            for(int j = 0; j < scount; j++) {
                if(need[i][j] != 0 ) {
                    flag = false;
                    index =j;
                }

            }
            //如果need 对接数据为0 回收数据
            if(flag && finish[i] == false){
                for(int a =0; a < scount; a++){
                    avialiable[a]+= max[i][a];
                    max[i][a] = 0;
                }
                finish[i] = true;
                fcount--;
            }
        }
        //保存
        save(max,allocation,avialiable,false);
    }

}

主函数代码

package Yinhangjia;

import java.util.Scanner;

/**
 * @author hrl
 * @date 2021年04月24日13:52
 */
public class Main {
/*
 *
 * @author hrl
 * @date 2021/4/24 14:39
 * @param null
 * @return null
 * 输入资源数目
3  
进程数目
5 
max
7 5 3
3 2 2
9 0 2
2 2 2
4 3 3
need
0 1 0
2 0 0
3 0 2
2 1 1
0 0 2
avaliable
3 3 2
*/
public static void main(String[] args) {
    boolean Choose = true;
    String flag;
    Scanner in = new Scanner(System.in);
    Banker banker = new Banker();


    banker.intit();//初始化

    banker.dispaly();//显示
    while (Choose == true) {
        banker.setRequest();
        System.out.println("您是否还要进行请求:y/n?");
        flag = in.nextLine();
        if (flag.endsWith("n")) {
            Choose = false;
        }
    }
}

}

测试数据也在上面了 。 欢迎白嫖 给个赞就行


  • 11
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值