操作系统 银行家算法 Java 实现

操作系统 银行家算法 Java 实现

目录:

  1. 银行家算法的基本原理
  2. 代码实现
  3. 测试结果截图

1. 银行家算法的基本原理

操作系统死锁避免——银行家算法

2. 代码实现

1). 资源分配表类 (SrcAllocTable) 与进程记录类 (Record)
public class SrcAllocTable {
    private int processNum;
    private int sourceNum;
    private Record[] table;
    private int[] sum;
    private int[] available;

    public SrcAllocTable(int[] sum, Record[] table) {
        // if(sum.length != table.length)
        //     throw XXXException;
        this.sum = sum;
        this.table = table;
        this.processNum = table.length;
        this.sourceNum = sum.length;
        this.available = sum.clone();
        for(int i = 0; i<sourceNum; i++)
            for(int j = 0; j<processNum; j++)
                available[i] -= table[j].getAllocation()[i];
    }

    public SrcAllocTable(SrcAllocTable table){
        this.processNum = table.getProcessNum();
        this.table = table.getTable().clone();
        this.sum = table.getSum().clone();
        this.available = table.getAvailable();
    }

    public Record[] getTable() {
        return table;
    }

    public int[] getAvailable() {
        return available;
    }

    public int[] getSum() {
        return sum;
    }

    public int getProcessNum() {
        return processNum;
    }

    public int getSourceNum() {
        return sourceNum;
    }

    @Override
    public String toString() {
        StringBuilder info = new StringBuilder();
        for(int i = 0; i<processNum; i++)
            info.append(table[i].toString()).append("\n");
        info.append("Available: ").append(Arrays.toString(available));
        return info.toString();
    }
}

class Record{
    private String proName;
    private int sourceNum;
    private int[] max;
    private int[] allocation;
    private int[] need;
    private boolean isFinished;

    public Record(String proName, int[] max, int[] allocation) {
        this.proName = proName;
        this.sourceNum = max.length;
        this.max = max;
        this.allocation = allocation;
        this.need = new int[sourceNum];
        for(int i = 0; i<sourceNum; i++)
            need[i] = max[i] - allocation[i];
        this.isFinished = false;
    }

    public int[] getAllocation() {
        return allocation;
    }

    public int[] getNeed() {
        return need;
    }

    public int getSourceNum() {
        return sourceNum;
    }

    public String getProName() {
        return proName;
    }

    public boolean isFinished() {
        return isFinished;
    }

    public void setFinished(boolean finished) {
        isFinished = finished;
    }

    @Override
    public String toString() {
        return proName + " "
                + "Max: " + Arrays.toString(max) + " "
                + "Allocation: " + Arrays.toString(allocation) + " "
                + "Need: " + Arrays.toString(need) + " "
                + "IsFinished: " + isFinished;
    }
	
	// 测试
    public static void main(String[] args){
        int[] max0 = {7, 5, 3};
        int[] allocation0 = {0, 1, 0};
        Record r0 = new Record("p0", max0, allocation0);

        int[] max1 = {3, 2, 2};
        int[] allocation1 = {2, 0, 0};
        Record r1 = new Record("p1", max1, allocation1);

        int[] max2 = {9, 0, 2};
        int[] allocation2 = {3, 0, 2};
        Record r2 = new Record("p2", max2, allocation2);

        Record[] table = {r0, r1, r2};
        int[] sum = {10, 5, 7};
        SrcAllocTable st = new SrcAllocTable(sum, table);
        System.out.println(st);
    }
}

2). 银行家类(实现银行家算法)
public class Banker {
    private SrcAllocTable srcTable;

    public Banker(SrcAllocTable table) {
        this.srcTable = table;
    }
	
	
	/**
     * 安全性检测
     * @param i 进程记录的编号
     * @param request 请求的资源数组
     * @return 是否安全
     */
    public boolean securityDetect(int i, int[] request) {
        boolean isSecurity = false;

        // 先复制整张资源分配表
        SrcAllocTable tmpTable = new SrcAllocTable(srcTable);
        showDebugInfo("Before allocation: ", tmpTable);

        // 1. 试探性分配资源
        Record[] table = tmpTable.getTable();
        int[] need = table[i].getNeed();
        int[] available = tmpTable.getAvailable();
        int[] allocated = table[i].getAllocation();
        for (int k = 0; k < request.length; k++) {
            need[k] -= request[k];
            available[k] -= request[k];
            allocated[k] += request[k];
        }

        showDebugInfo("After allocation: ", tmpTable);

        int procCount = 0;
        StringBuilder procQueue = new StringBuilder();
        int procNum = tmpTable.getProcessNum(); // 尚未完成的进程或者说表中 isFinished 为 false 的记录的数量
        int srcNum = tmpTable.getSourceNum(); // 资源种类数

        for(int n = 0; n<procNum; n++) {
            for (int k = 0; k < procNum; k++) { // 外层循环遍历资源表中的各个进程记录
                int count = 0;

                if(table[k].isFinished())
                   continue;
                for (int j = 0; j < srcNum; j++) // 对每个进程的资源进行判断
                    if (table[k].getNeed()[j] <= available[j])
                        count++;

                if (count == srcNum) { // 如果进程的 need 比 available 要少那么就是可以完成的
                    table[k].setFinished(true);
                    for (int j = 0; j < srcNum; j++) {
                        table[k].getNeed()[j] = 0;
                        available[j] += table[k].getAllocation()[j];
                        table[k].getAllocation()[j] = 0;
                    }
                    procQueue.append(table[k].getProName() + " ");
                    procCount++;
                    showDebugInfo("Security Detection: ", tmpTable);
                }
            }
        }

        showDebugInfo("Security Detection Result: ", tmpTable);
        System.out.println("Security Queue: " + procQueue.toString());

        if(procNum == procCount)
            isSecurity = true;
        else
            System.out.println("The request of source can't pass the security detection");

        return isSecurity;
    }


	/**
     * 是否可为进程分配所请求的资源
     * 检测步骤:
     *      1. request i <= need i ?
     *      2. request i <= available ?
     *      3. 是否可以通过安全性检测
     * @param i 进程记录编号
     * @param request 请求分配的资源
     * @return 是否可以为请求进程分配资源
     */
    public boolean ifAllocate(int i, int[] request) {

        // 1. request <= need
        // 2. request <= available
        int[] need = srcTable.getTable()[i].getNeed();
        int[] available = srcTable.getAvailable();
        for (int k = 0; k < request.length; k++)
            if (request[k] > need[k] || request[k] > available[k]) {
                System.out.println("Sorry, the requested source may out of needed or available source!");
                return false;
            }

        // 3. security Detect
        return securityDetect(i, request);
    }

	// 打印资源分配表的情况
    public void showDebugInfo(String info, SrcAllocTable tmpTable){
        System.out.println(info);
        System.out.println(tmpTable);
        System.out.println("------------------------------------------");

    }

    public static void main(String[] args) {
        int[] max0 = {7, 5, 3};
        int[] allocation0 = {0, 1, 0};
        Record r0 = new Record("p0", max0, allocation0);

        int[] max1 = {3, 2, 2};
        int[] allocation1 = {2, 0, 0};
        Record r1 = new Record("p1", max1, allocation1);

        int[] max2 = {9, 0, 2};
        int[] allocation2 = {3, 0, 2};
        Record r2 = new Record("p2", max2, allocation2);

        int[] max3 = {2, 2, 2};
        int[] allocation3 = {2, 1, 1};
        Record r3 = new Record("p3", max3, allocation3);

        int[] max4 = {4, 3, 3};
        int[] allocation4 = {0, 0, 2};
        Record r4 = new Record("p4", max4, allocation4);

        Record[] table = {r0, r1, r2, r3, r4};
        int[] sum = {10, 5, 7};
        SrcAllocTable st = new SrcAllocTable(sum, table);
        System.out.println(st);

        // Banker
        Banker banker = new Banker(st);


        int i = 1;
        int[] request = {1, 0, 2};

        System.out.println(banker.ifAllocate(i, request));
    }
}

3. 测试结果:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值