操作系统实验之银行家算法(Java升级版)

前言

这次较上一篇文章更加透彻地展示了银行家算法,分析步骤和上一篇一样,直接上代码

代码实现

Processes.class

/**
 * 进程类,包含多个进程的资源情况以及系统资源的情况
 */

import java.util.ArrayList;
import java.util.Scanner;

public class Processes {
    private String[] resourceName;    //系统资源名称
    private boolean[] isDel;          //是否已排除
    private Integer[][] maxNum;       //Pi的需求资源数量(最大需求资源数量)
    private Integer[][] allocation;   //已分配给该进程的资源
    private Integer[][] needNum;      //还需要的资源数量
    private Integer AVAILABLE_COUNT_Y;//资源的种类数量
    private Integer PROCESSES_COUNT;  //进程的个数
    private ArrayList<String> safe;    //安全序列

    public ArrayList<String> getSafe() {
        return safe;
    }

    public Processes() {
        Init();
    }

    public boolean getIsDel(int i) {
        return isDel[i];
    }

    public Integer getAVAILABLE_COUNT_Y() {
        return AVAILABLE_COUNT_Y;
    }

    public Integer getPROCESSES_COUNT() {
        return PROCESSES_COUNT;
    }

    public String getResourceName(int j) {
        return resourceName[j];
    }

    public Integer getMaxNum(int i,int j) {
        return maxNum[i][j];
    }

    public Integer getAllocation(int i,int j) {
        return allocation[i][j];
    }

    public void setAllocation(int i,int j,Integer allo) {
        allocation[i][j] = allo;
    }

    public Integer getNeedNum(int i,int j) {
        return needNum[i][j];
    }

    public void setNeedNum(int i,int j,Integer need) {
        needNum[i][j] = need;
    }

    /**
     * 初始化
     */
    public void Init() {
        System.out.print("请输入资源的种类数量:");
        Scanner input = new Scanner(System.in);
        AVAILABLE_COUNT_Y = input.nextInt();
        resourceName = new String[AVAILABLE_COUNT_Y];
        System.out.println("请输入各类资源的名称:");
        for (int i = 0; i < AVAILABLE_COUNT_Y; i++) {
            System.out.print("资源" + (i+1) + "的名称:");
            resourceName[i] = input.next();
        }

        System.out.println("请输入进程的个数:");
        PROCESSES_COUNT = input.nextInt();
        maxNum = new Integer[PROCESSES_COUNT][AVAILABLE_COUNT_Y];
        allocation = new Integer[PROCESSES_COUNT][AVAILABLE_COUNT_Y];
        needNum = new Integer[PROCESSES_COUNT][AVAILABLE_COUNT_Y];
        for (int i = 0; i < PROCESSES_COUNT; i++) {
            System.out.println("请输入进程P" + i + "对" + AVAILABLE_COUNT_Y + "类资源的最大需求:");
            for (int j = 0; j < AVAILABLE_COUNT_Y; j++) {
                System.out.print(resourceName[j] + ":");
                maxNum[i][j] = input.nextInt();
            }

            System.out.println("请输入进程P" + i + "已申请到的各类资源数:");
            for (int j = 0; j < AVAILABLE_COUNT_Y; j++) {
                System.out.print(resourceName[j] + ":");
                allocation[i][j] = input.nextInt();
            }

            for (int j = 0; j < AVAILABLE_COUNT_Y; j++) {
                needNum[i][j] = maxNum[i][j] - allocation[i][j];
            }
        }
        isDel = new boolean[PROCESSES_COUNT];
        for (int i = 0; i < PROCESSES_COUNT; i++) {
            isDel[i] = false;
        }
        safe = new ArrayList<>();
    }

    public void Del(int i){
        isDel[i] = true;
        safe.add("P" + i);
    }
}

Banker.class

/**
 * 银行家算法
 */

import java.util.ArrayList;
import java.util.Scanner;

public class Banker {
    private Integer[][] request;  //进程的请求向量
    private Integer[] num;        //资源的总数量
    private Integer[] available;  //可利用资源向量
    private int num1;             //进程编号num

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

    /**
     * 银行家算法
     */
    public Processes Bank() {
        Processes processes = new Processes();
        Scanner input = new Scanner(System.in);
        System.out.println("请输入各类资源的数量:");
        num = new Integer[processes.getAVAILABLE_COUNT_Y()];
        for (int i = 0; i < processes.getAVAILABLE_COUNT_Y(); i++) {
            System.out.print(processes.getResourceName(i) + ":");
            num[i] = input.nextInt();
        }
        request = new Integer[processes.getPROCESSES_COUNT()][processes.getAVAILABLE_COUNT_Y()];
        available = new Integer[processes.getAVAILABLE_COUNT_Y()];
        //给系统可利用资源向量赋值
        available = num;
        for (int i = 0; i < processes.getPROCESSES_COUNT(); i++) {
            for (int j = 0; j < processes.getAVAILABLE_COUNT_Y(); j++) {
                available[j] = available[j] - processes.getAllocation(i, j);
            }
        }
        System.out.println("T0时刻的安全性:");
        printSystemVariable(processes);
        if (Safity(processes)){
            System.out.print("此时存在一个安全序列");
            System.out.println("故当前可分配!");
            //给请求向量赋值
            setRequest(processes);

        }else {
            System.out.println("当前系统处于不安全状态,故不存在安全序列。");
            System.exit(0);
        }

        return processes;
    }

    /**
     * 开始执行算法
     * @param processes
     */
    public void BankBegin(Processes processes) {
        //判断是否能都满足请求条件
        boolean T = true;
        int trueCount = 0;
        for (int j = 0; j < processes.getAVAILABLE_COUNT_Y(); j++) {
            if (request[num1][j] <= processes.getNeedNum(num1, j)) {//判断Request是否小于Need
                if (request[num1][j] <= available[j]) {//判断Request是否小于Alloction
                    trueCount++;
                    if (trueCount == processes.getAVAILABLE_COUNT_Y()) {
                        for (int i = 0; i < processes.getAVAILABLE_COUNT_Y(); i++) {
                            available[i] = available[i] - request[num1][i];
                            processes.setAllocation(num1, i, (processes.getAllocation(num1, i) + request[num1][i]));
                            processes.setNeedNum(num1, i, (processes.getNeedNum(num1, i) - request[num1][i]));
                        }
                        break;
                    }
                } else {
                    System.out.println("当前没有足够的资源可分配,进程P" + num1 + "需等待。");
                    T = false;
                }
            } else {
                System.out.println("进程P" + num1 + "请求已经超出最大需求量Need.");
                T = false;
            }
        }
        if (T == true) {
            printSystemVariable(processes);
            System.out.println("预分配完成,进入安全性算法:");
            if (Safity(processes)){
                System.out.print("此时存在一个安全序列");
                System.out.print(",");
                System.out.println("故当前可分配!");
            }else {
                System.out.println("当前系统处于不安全状态,故不存在安全序列。");
            }
        }
    }

    /**
     * 安全性算法
     */
    public boolean Safity(Processes processes) {
        Integer[] work = new Integer[processes.getAVAILABLE_COUNT_Y()];     //工作向量Work
        for (int i = 0; i < processes.getAVAILABLE_COUNT_Y(); i++) {
            work[i] = available[i];
        }
        String[] finish = new String[processes.getPROCESSES_COUNT()];       //工作向量Finish
        for (int j = 0; j < finish.length; j++) {
            finish[j] = "false";
        }

        for (int i = 0; i < processes.getPROCESSES_COUNT(); i++) {
            ArrayList<String> isFind = new ArrayList<>();
            //如果进程没有被排除,则进行判断
            if (!(processes.getIsDel(i))) {
                //判断第二步的条件
                if (finish[i].compareTo("false") == 0) {
                    for (int j = 0; j < processes.getAVAILABLE_COUNT_Y(); j++) {
                        if (processes.getNeedNum(i, j) <= work[j]) {
                            isFind.add("true");
                        }
                    }
                }
            }
            //Pi所需资源均满足第二步条件时,顺利执行
            if (isFind.size() == processes.getAVAILABLE_COUNT_Y()) {
                for (int k = 0; k < processes.getAVAILABLE_COUNT_Y(); k++) {
                    work[k] = work[k] + processes.getAllocation(i, k);
                    finish[i] = "true";
                }
                processes.Del(i);
            }

        }

        return true;
    }

    /**
     * 打印资源数据
     */
    public void printSystemVariable(Processes processes) {
        System.out.println("此时资源分配量如下:");
        System.out.println("进程  " + "   Max   " + "   Alloction " + "    Need  " + "     Available ");
        for (int i = 0; i < processes.getPROCESSES_COUNT(); i++) {
            System.out.print("P" + i + "     ");
            for (int j = 0; j < processes.getAVAILABLE_COUNT_Y(); j++) {
                System.out.print(processes.getMaxNum(i, j) + "  ");
            }
            System.out.print("|  ");
            for (int j = 0; j < processes.getAVAILABLE_COUNT_Y(); j++) {
                System.out.print(processes.getAllocation(i, j) + "  ");
            }
            System.out.print("|  ");
            for (int j = 0; j < processes.getAVAILABLE_COUNT_Y(); j++) {
                System.out.print(processes.getNeedNum(i, j) + "  ");
            }
            System.out.print("|  ");
            if (i == 0) {
                for (int j = 0; j < processes.getAVAILABLE_COUNT_Y(); j++) {
                    System.out.print(available[j] + "  ");
                }
            }
            System.out.println();
        }
    }


}

BankerTest.class

/**
 * 银行家算法测试类
 */

import java.util.Scanner;

public class BankerTest {
    public static void main(String[] args) {
        //是否继续请求
        boolean Choose = true;
        String string;
        Scanner in = new Scanner(System.in);
        Banker banker = new Banker();
        Processes processes = banker.Bank();
        while (Choose == true) {
            banker.setRequest(processes);
            System.out.println("您是否还要进行请求:y/n?");
            string = in.nextLine();
            if (string.endsWith("n")) {
                Choose = false;
            }
        }
    }
}
发布了56 篇原创文章 · 获赞 51 · 访问量 4763

猜你喜欢

转载自blog.csdn.net/qq_34504626/article/details/103987820