银行家算法 : java实现(基于课本)

银行家算法 : java实现(基于课本)

属性

需要在构造方法中传入的
  1. 整型Resources , 用于表名可用资源种类数量, 共有几种资源
  2. 整型Process, 用于表名进程数量, 共有几个进程
  3. 整型数组Available, 用于表名每类可用资源的数量
  4. 整形矩阵Max, 用于表名每个进程所需的总的资源量
  5. 整型矩阵Allocation, 用于表示每个进程目前已经拥有的每类资源资源的资源数量
其他属性
  1. 整形矩阵Need, 用于表示每个进程目前需要的每类资源资源的资源数量
  2. Available2, Allocation2, Need2, 分别时以上三个数据结构的备份, 用于安全性检测, 不破环原数据结构
  3. 整型数组work, 用于表示目前可用的资源数(在检测安全性时使用)
  4. 布尔数组finish, 安全性检测时每一个进程完成后, 对应的索引改为true

方法

public
  1. BankerAlgorithm() 构造方法
  2. Algorithm() 银行家算法
  3. UpdateResources() 更新数据的算法
private
  1. setNeed() 构造Need矩阵的方法
  2. reSetNeed() 刷新需求矩阵的方法
  3. reCopying() 复制备份的方法
  4. rebuild() 用于初始化work和finish的方法
  5. reFinish() 用于刷新work和finish数组的方法
  6. able() 用于判断work中的值够不够减的方法
  7. isSecurity() 用于判断请求是不是安全的方法
  8. findThePath() 如果安全,用于排列出一个安全组合的方法

大体执行流程

传入参数调用构造方法后, 使用银行家算法Algorithm(), 传入请求参数(那个进程申请什么资源多少)

Algorithm()调用setNeed()建立Need矩阵, 经过两部初始判断后调用isSecurity()方法判断请求是否安全,

isSecurity()建立work和finish, 通过判断后返回布尔值给Algorithm(), 如果安全就调用findThePath()找到安全组合, 并输出

测试类中可选择更新数据, 也可选择不更新数据UpdateResources()

需要注意

所有的属性貌似在对象创建之初先于构造方法创建,
也就是说如果属性数组的大小由其他数值属性(需要被构造方法赋值)来确定时,
因为在构造方法赋值前,所使用的初始数值为0, 所以就是说属性数组大小为零,
所以任何此类数组属性都可由动态数组代替(ArrayList/LinkedList).

代码

算法类
import java.util.ArrayList;

public class BankerAlgorithm {

    public int Resources;      //资源数量
    public int Process;        //进程数量
    public int[] Available;    //可用资源向量
    public int[][] Max;        //最大需求矩阵
    public int[][] Allocation; //分配矩阵

    public BankerAlgorithm(int Resources, int Process, int[] Available, int[][] Max, int[][] Allocation){
        //构造方法
        this.Process = Process;
        this.Resources = Resources;
        this.Allocation = Allocation;
        this.Max = Max;
        this.Available = Available;
    }

    /**
     * 所有的属性貌似在对象创建之初先于构造方法创建,
     * 也就是说如果属性数组的大小由其他数值属性(需要被构造方法赋值)来确定时,
     * 因为在构造方法赋值前,所使用的初始数值为0,所以就是说属性数组大小为零
     * 所以任何此类数组属性都可由动态数组代替(ArrayList/LinkedList)
    * */
    private final ArrayList<ArrayList<Integer>> Need = new ArrayList<>();

    private void setNeed(){
        for(int i=0;i<Process;i++){
            Need.add(i,new ArrayList<>());
            for(int j=0;j<Resources;j++){
                Need.get(i).add(j,(Max[i][j] - Allocation[i][j]));
            }
        }
    }

    private void reSetNeed(){
        Need.clear();
        setNeed();
    }

    //Available Allocation Need的备份
    private final ArrayList<Integer> Available2 = new ArrayList<>();
    private final ArrayList<ArrayList<Integer>> Allocation2 = new ArrayList<>();
    private final ArrayList<ArrayList<Integer>> Need2 = new ArrayList<>();

    private void reCopying(){        //用于复制备份
        Available2.clear();
        Allocation2.clear();
        Need2.clear();
        for(int i=0;i<Process;i++){
            Allocation2.add(i,new ArrayList<>());
            Need2.add(i,new ArrayList<>());
            for(int j=0;j<Resources;j++){
                Allocation2.get(i).add(j,Allocation[i][j]);
                Need2.get(i).add(j,Need.get(i).get(j));
            }
        }
        for(int i=0;i<Resources;i++){
            Available2.add(i,Available[i]);
        }
    }

    public void Algorithm(int i, int[] Request){    //进程i向系统提出资源请求
        reSetNeed();
        boolean f = true;           //要求量小于需求量
        for(int j=0;j<Resources;j++){
            if (Request[j] > Need.get(i).get(j)) {
                f = false;
                break;
            }
        }
        if(f){
            boolean f2 = true;          //要求量小于剩余量
            for(int j=0;j<Resources;j++){
                if (Request[j] > Available[j]) {
                    f2 = false;
                    break;
                }
            }
            if(f2){
                reCopying();
                for(int j=0;j<Resources;j++){
                    Available2.set(j,Available2.get(j)-Request[j]);
                    Allocation2.get(i).set(j,(Allocation2.get(i).get(j)+Request[j]));
                    Need2.get(i).set(j,(Need2.get(i).get(j)-Request[j]));
                }
                if(isSecurity()){
                    ArrayList<Integer> path = findThePath();
                    for(int p:path)
                        System.out.print("p"+p+" ");
                }else {
                    System.out.println("此请求不安全!");
                }
            }else
                System.out.println("请求不通过: 请求资源数量大于现有资源量!");
        }else
            System.out.println("请求不通过: 申请资源数量大于自身所需!");
    }

    //work和finish
    private final ArrayList<Integer> work = new ArrayList<>();
    private final ArrayList<Boolean> finish = new ArrayList<>();

    private void rebuild(){         //用于初始化work和finish
        for(int i=0;i<Resources;i++){
            work.add(Available2.get(i));
        }
        for(int i=0;i<Process;i++)
            finish.add(false);
    }

    private void reFinish(){            //用于刷新work和finish数组
        work.clear();
        for(int i=0;i<Resources;i++){
            work.add(Available2.get(i));
        }
        finish.clear();
        for(int i=0;i<Process;i++)
            finish.add(false);
    }

    private boolean able(int i){        //用于判断work中的值够不够减
        boolean f = true;
        for(int j=0;j<Resources;j++){
            if (work.get(j) < Need2.get(i).get(j)) {
                f = false;
                break;
            }
        }
        return f;
    }

    private boolean isSecurity(){       //用于判断是不是安全
        rebuild();
        boolean flag = false;
        for(int n=0;n<Process;n++) {
            if(!flag) {
                flag = true;
                for (int i = 0; i < Process; i++) {
                    if (able(i) && !finish.get(i)) {
                        for (int j = 0; j < Resources; j++) {
                            work.set(j,work.get(j)+Allocation2.get(i).get(j));
                            Allocation2.get(i).set(j,0);
                        }
                        finish.set(i,true);
                    }
                }
                for (int i = 0; i < Process; i++) {
                    if (!finish.get(i)) {
                        flag = false;
                        break;
                    }
                }
            }
        }
        return flag;
    }

    private ArrayList<Integer> findThePath(){   //用于排列出一个安全组合
        reCopying();
        rebuild();
        reFinish();
        ArrayList<Integer> Path = new ArrayList<>();
        boolean flag = false;
        for(int n=0;n<Process;n++) {
            if(!flag) {
                flag = true;
                for (int i = 0; i < Process; i++) {
                    if (able(i) && !finish.get(i)) {
                        for (int j = 0; j < Resources; j++) {
                            work.set(j,work.get(j)+Allocation2.get(i).get(j));
                            Allocation2.get(i).set(j,0);
                        }
                        finish.set(i,true);
                        Path.add(i);
                    }
                }
                for (int i = 0; i < Process; i++) {
                    if (!finish.get(i)) {
                        flag = false;
                        break;
                    }
                }
            }
        }
        return Path;
    }

    public void UpdateResources(int n, int[] Request){  //执行操作, 并更新数据
        if(isSecurity()) {
            for (int i = 0; i < Resources; i++) {
                Available[i] = Available[i] - Request[i];
                Allocation[n][i] = Allocation[n][i] + Request[i];
                Need.get(n).set(i, Need.get(n).get(i) - Request[i]);
            }
        }
    }

}

测试类(两个测试案例)
public class Test {

    public static void test1(){
        int Resources = 3;
        int Process = 5;
        int[] Available = new int[]{3,3,2};
        int[][] Max = new int[Process][Resources];
        int[][] Allocation = new int[Process][Resources];
        int[] max = new int[]{
                7,5,3,3,2,2,9,0,2,2,2,2,4,3,3
        };
        int[] allocation = new int[]{
                0,1,0,2,0,0,3,0,2,2,1,1,0,0,2
        };
        for(int i=0;i<Process;i++){
            for(int j=0;j<Resources;j++){
                Max[i][j] = max[i*Resources+j];
                Allocation[i][j] = allocation[i*Resources+j];
            }
        }
        BankerAlgorithm banker = new BankerAlgorithm(Resources,Process,Available,Max,Allocation);
        int[] request1 = new int[]{1,0,2};
        //P1发出请求Request(1,0,2),执行银行家算法
        banker.Algorithm(1,request1);
        banker.UpdateResources(1,request1);

        System.out.println();

        int[] request2 = new int[]{3,3,0};
        banker.Algorithm(4,request2);
        banker.UpdateResources(1,request1);
    }

    public static void test2(){
        int Resources = 3;
        int Process = 5;
        int[] Available = new int[]{2,1,0};
        int[][] Max = new int[Process][Resources];
        int[][] Allocation = new int[Process][Resources];
        int[] max = new int[]{
                7,5,3,3,2,2,9,0,2,2,2,2,4,3,3
        };
        int[] allocation = new int[]{
                0,3,0,3,0,2,3,0,2,2,1,1,0,0,2
        };
        for(int i=0;i<Process;i++){
            for(int j=0;j<Resources;j++){
                Max[i][j] = max[i*Resources+j];
                Allocation[i][j] = allocation[i*Resources+j];
            }
        }
        BankerAlgorithm banker = new BankerAlgorithm(Resources,Process,Available,Max,Allocation);
        int[] request0 = new int[]{0,2,0};
        banker.Algorithm(0,request0);
    }

    public static void main(String[] args) {
        test1();
        System.out.println();
        test2();
    }

}

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值