Java实现银行家算法示例代码

使用 GPT-4o Mini 回答,作者 GPT4oMini.app

问题:

用JAVA语言实现: 银行家算法 设Requesti是进程Pi的请求向量,如果Requesti[j]=K,表示进程Pi需要K个Rj类型的资源。当Pi发出资源请求后,系统按下述步骤进行检查: (1)如果Requesti[j]≤Need[i,j],便转向步骤(2);否则认为出错,因为它所需要的资源数已超过它所宣布最大值。 (2)如果Requesti[j]≤Available[j],便转向步骤(3);否则,表示尚无足够资源,Pi须等待。 (3)系统试探着把资源分配给进程Pi,并修改下面数据结构中的数值: Available[j]=Available[j]-Requesti[j]; Allocation[i,j]=Allocation[i,j]+Requesti[j];
Need[i,j]=Need[i,j]-Requesti[j]; 系统执行安全性算法,检查此次资源分配后,系统是否处于安全状态。若安全,才正式将资源分配给进程Pi,以完成本次分配;否则,将本次的试探分配作废,恢复原来的资源分配状态,让进程Pi等待。 3、安全性算法 1)设置两个向量: 工作向量Work: 它表示系统可提供给进程继续运行所需的各类资源数目,它含有m个元素,在执行安全算法开始时,Work=Available; 工作向量Finish: 它表示系统是否有足够的资源分配给进程,使之运行完成。开始时先做Finish[i]=false; 当有足够资源分配给进程时, 再令Finish[i]=true。 2)从进程集合中找到一个能满足下述条件的进程: 
Finish[i]=false; Need[i,j]≤Work[j];若找到,执行 (3),否则,执行 (4) 3)当进程Pi获得资源后,可顺利执行,直至完成,并释放出分配给它的资源,故应执行: Work[j]=Work[j]+Allocation[i,j]; Finish[i]=true; go to step 2; 4)如果所有进程的Finish[i]=true都满足, 则表示系统处于安全状态;否则,系统处于不安全状态

答案:

下面是一个用Java实现的银行家算法的示例代码。这个代码实现了资源请求的处理和安全性检查。

import java.util.Arrays;
import java.util.Scanner;

public class BankersAlgorithm {
    private int[][] max; // 最大需求矩阵
    private int[][] allocation; // 分配矩阵
    private int[][] need; // 需求矩阵
    private int[] available; // 可用资源向量
    private int numProcesses; // 进程数量
    private int numResources; // 资源种类数量

    public BankersAlgorithm(int numProcesses, int numResources) {
        this.numProcesses = numProcesses;
        this.numResources = numResources;
        max = new int[numProcesses][numResources];
        allocation = new int[numProcesses][numResources];
        need = new int[numProcesses][numResources];
        available = new int[numResources];
    }

    public void input() {
        Scanner scanner = new Scanner(System.in);

        System.out.println("输入最大需求矩阵:");
        for (int i = 0; i < numProcesses; i++) {
            System.out.print("进程 P" + i + ": ");
            for (int j = 0; j < numResources; j++) {
                max[i][j] = scanner.nextInt();
            }
        }

        System.out.println("输入分配矩阵:");
        for (int i = 0; i < numProcesses; i++) {
            System.out.print("进程 P" + i + ": ");
            for (int j = 0; j < numResources; j++) {
                allocation[i][j] = scanner.nextInt();
            }
        }

        System.out.println("输入可用资源向量:");
        for (int j = 0; j < numResources; j++) {
            available[j] = scanner.nextInt();
        }

        // 计算需求矩阵
        for (int i = 0; i < numProcesses; i++) {
            for (int j = 0; j < numResources; j++) {
                need[i][j] = max[i][j] - allocation[i][j];
            }
        }
    }

    public boolean requestResources(int processId, int[] request) {
        // 检查请求是否小于等于需求
        for (int j = 0; j < numResources; j++) {
            if (request[j] > need[processId][j]) {
                System.out.println("错误: 请求超过最大需求.");
                return false;
            }
        }

        // 检查请求是否小于等于可用资源
        for (int j = 0; j < numResources; j++) {
            if (request[j] > available[j]) {
                System.out.println("资源不足, 进程 P" + processId + " 需要等待.");
                return false;
            }
        }

        // 尝试分配资源
        for (int j = 0; j < numResources; j++) {
            available[j] -= request[j];
            allocation[processId][j] += request[j];
            need[processId][j] -= request[j];
        }

        // 检查系统是否安全
        if (isSafe()) {
            System.out.println("资源分配成功给进程 P" + processId);
            return true;
        } else {
            // 回滚
            for (int j = 0; j < numResources; j++) {
                available[j] += request[j];
                allocation[processId][j] -= request[j];
                need[processId][j] += request[j];
            }
            System.out.println("资源分配失败, 系统不安全.");
            return false;
        }
    }

    private boolean isSafe() {
        boolean[] finish = new boolean[numProcesses];
        int[] work = Arrays.copyOf(available, numResources);
        int count = 0;

        while (count < numProcesses) {
            boolean found = false;
            for (int p = 0; p < numProcesses; p++) {
                if (!finish[p]) {
                    // 检查需求是否可以满足
                    boolean canAllocate = true;
                    for (int j = 0; j < numResources; j++) {
                        if (need[p][j] > work[j]) {
                            canAllocate = false;
                            break;
                        }
                    }
                    if (canAllocate) {
                        // 资源分配给进程 p
                        for (int j = 0; j < numResources; j++) {
                            work[j] += allocation[p][j];
                        }
                        finish[p] = true;
                        found = true;
                        count++;
                    }
                }
            }
            if (!found) {
                break; // 没有找到可以分配的进程
            }
        }

        // 检查是否所有进程都完成
        return count == numProcesses;
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.print("输入进程数量: ");
        int numProcesses = scanner.nextInt();
        System.out.print("输入资源种类数量: ");
        int numResources = scanner.nextInt();

        BankersAlgorithm bankersAlgorithm = new BankersAlgorithm(numProcesses, numResources);
        bankersAlgorithm.input();

        System.out.print("输入请求进程ID: ");
        int processId = scanner.nextInt();
        int[] request = new int[numResources];
        System.out.print("输入请求资源: ");
        for (int j = 0; j < numResources; j++) {
            request[j] = scanner.nextInt();
        }

        bankersAlgorithm.requestResources(processId, request);
    }
}

代码说明:

  1. 类定义BankersAlgorithm类包含了银行家算法的实现。
  2. 输入方法input()方法用于输入最大需求矩阵、分配矩阵和可用资源向量。
  3. 资源请求方法requestResources(int processId, int[] request)方法用于处理进程的资源请求,并检查系统是否处于安全状态。
  4. 安全性检查isSafe()方法实现了安全性算法,检查系统是否处于安全状态。
  5. 主方法main方法用于运行程序,获取用户输入并处理资源请求。

使用方法:

  1. 运行程序。
  2. 输入进程数量和资源种类数量。
  3. 输入最大需求矩阵、分配矩阵和可用资源向量。
  4. 输入请求进程ID和请求的资源数量。
  5. 程序将输出资源分配的结果。