Java 实现OS进程安全检测算法之银行家算法(Bankers Algorithm)

文章目录

    • 数据结构介绍:
    • 程序结构
    • 银行家算法bank()函数
    • 安全性算法safe()函数
    • Java 代码实现
    • 结果测试:

编写银行家算法的模拟程序.
该程序应该能够循环检查每一个提出请求的银行客户并且能判断这一请求是否安全.并把有关请求和相应决定的列表输出.

数据结构介绍:

可利用资源向量     int  Available[m]   m为资源种类
最大需求矩阵       int  Max[n][m]     n为进程的数量
分配矩阵           int  Allocation[n][m] 
还需资源矩阵       int  need[i][j]= Max[i][j]-Allocation[i][j]
申请资源数量       int  Request[m]   
工作向量           int  Work[m], int Finish[n] 

程序结构

程序共有以下五个部分:
(1).初始化init():输入进程数量、资源种类、资源可利用量、进程资源已分配量、进程最大需求量
(2).当前安全性检查safe():用于判断当前状态安全。
(3).银行家算法bank():进行银行家算法模拟实现的模块
(4).显示当前状态show():显示当前资源分配详细情况
(5).主程序main():逐个调用初始化、显示状态、安全性检查、银行家算法函数,使程序有序的进行。

银行家算法bank()函数

Requesti:进程Pi的请求向量。 0<=j<=m-1
(1) 若 Requesti[j] ≤ Need[i,j],转向(2),否则出错。
(2) 若 Requesti[j] ≤ Available[j],转向(3),否则等待。
(3) 系统试探着把资源分配给进程Pi,修改下面内容:
Available[j] = Available[j] – Requesti[j];
Allocation[i,j] = Allocation[i,j] + Requesti[j];
Need[i,j] = Need[i,j] –Requesti[j];
(4) 试分配后,执行安全性算法,检查此次分配后系统是否处于安全状态。若安全,才正式分配;否则,此次试探性分配作废,进程Pi等待。

安全性算法safe()函数

(1) 初始化:设置两个向量Work(1×m)和Finish(1×n)
Work – 系统可提供给进程继续运行所需各类资源数,初态赋值Available
Finish – 系统是否有足够资源分配给进程,初值false.
(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 (2).
(4) 若所有进程Finish[i] = true,表示系统处于安全状态,否则处于不安全状态。

Java 代码实现

package com.dhl.beyond.os_bank;

import java.util.Scanner;

public class Bank {
     
    //数据结构
    int N = 100; //进程的最大数
    int M = 100; //资源的最大数
    String[] Name = new String[100]; //资源的名称
    int[][] Max = new int[100][100];//最大需求矩阵
    int[] Avaliable = new int[100]; //可用资源矩阵
    int[][] Allocation = new int[100][100]; //已经分配资源矩阵
    int[][] Need = new int[100][100];//还需分配资源矩阵
    int[] Request = new int[100];//请求资源向量
    int[] Security = new int[100]; //存放 安全序列
    int[] Work = new int[100]; //存放 系统可提供的资源
    boolean[] Finish = new boolean[50]; //返回是否是安全序列

    //显示资源分配矩阵
    public void showdata() {
     
        System.out.println("************************************");
        System.out.print("系统目前可用的资源[Avaliable]:\n");
        for (int i = 0; i < M; i++)
            System.out.print(Name[i] + "   ");
        System.out.println(" ");
        for (int j = 0; j < M; j++)
            System.out.printf("%d    ", Avaliable[j]); //输出可用的资源
        System.out.println();
        System.out.println("系统当前的资源分配情况如下:");
        System.out.println("          Max                 Allocation         Need");
        System.out.print("进程名     ");
        for (int j = 0; j < 3; j++) {
     
            for (int i = 0; i < M; i++) {
     
                System.out.print(Name[i] + "  "); //打印资源的名称
            }
            System.out.print("           ");
        }
        System.out.println();
        for (int i = 0; i < N; i++) {
     
            System.out.printf(" P%d       ", i);
            for (int j = 0; j < M; j++) {
     
                System.out.printf("%d    ", Max[i][j]);
            }
            System.out.print("      ");
            for (int j = 0; j < M; j++) {
     
                System.out.printf("%d  ", Allocation[i][j]);
            }
            System.out.print("           ");
            for (int j = 0; j < M; j++) {
     
                System.out.printf("%d  ", Need[i][j]);
            }
            System.out.println();
        }
    }

    //安全性算法
    public int safe() {
     
        int k = 0;
        for (int j = 0; j < N; j++) {
     
            Finish[j] = false;
        }
        for (int j = 0; j < M; j++) {
     
            Work[j] = Avaliable[j];
        }
        for (int i = 0; i < N; i++) {
     
            int apply = 0;
            for (int j = 0; j < M; j++) {
     
                if (Finish[i] == false && Need[i][j] <= Work[j]) {
     
                    apply++;
                    if (apply == M) {
      //直到找到每种资源都小于 可供利用资源数时才可以进行分配
                        for (int p = 0; p < M; p++) {
     
                            Work[p] = Work[p] + Allocation[i][p];  //改变  系统可提供的资源值
                        }
                        Finish[i] = true;
                        Security[k] = i;
                        k++;
                        i = -1; //保证每次查询都重第一个进程开始

                    }
                }
            }
        }
        for (int i = 0; i < N; i++) {
     
            if (Finish[i] == false) {
     
                System.out.println("系统不安全!");
                return -1;
            }
        }

        System.out.println("系统是安全的!");
        System.out.println("存在一个安全序列如下:");
        for (int i = 0; i < N; i++) {
     
            System.out.printf("P%d", Security[i]);
            if (i < N - 1)
                System.out.print("-->");
        }
        System.out.println();
        return 0;
    }


    //利用银行家算法对申请资源进行尝试分配
    public void bank() {
     
        char ch = 'y';
        int allow = 1;
        System.out.printf("请输入请求分配资源的进程号(0-%d):", N - 1);
        Scanner input = new Scanner(System.in);
        int i = input.nextInt();//输入须申请资源的进程号
        System.out.printf("请输入进程P%d要申请的资源个数: \n", i);
        for (int j = 0; j < M; j++) {
     
            System.out.print(Name[j]+": ");
            Request[j] = input.nextInt(); //输入需要 申请的资源
        }
        for (int j = 0; j < M; j++) {
     
            if (Request[j] > Need[i][j]) {
     //判断申请是否大于需求,若大于测出错
                System.out.printf("进程P%d申请的资源大于它需要的资源", i);
                System.out.print("分配不合理,不与分配! \n");
                showdata();
                ch = 'm';
                break;
            } else {
     
                if (Request[j] > Avaliable[j]) {
     //判斷申请是否大于当前可分配资源,若大于则出错
                    System.out.printf("进程%d申请的资源大于系统现在可利用的资源", i);
                    System.out.println("");
                    System.out.printf("系统尚无足够资源,不予分配!\n");
                    showdata();
                    System.out.println("");
                    ch = 'm';
                    break;
                } else if (Request[j] > Avaliable[j]) {
     //判断申请是否大于当前可分配资源,若大于则出错
                    System.out.printf("进程%d申请的资源大于系统现在可利用的资源", i);
                    System.out.println("");
                    System.out.printf("系统向无足够资源,不子分配! \n");
                    showdata();
                    System.out.println("");
                    ch = 'm';
                    break;
                }
            }
        }
        if (ch == 'y') {
     
            //根据进程等求量变找资源
            for (int j = 0; j < M; j++) {
     
                Avaliable[j] = Avaliable[j] - Request[j];
                Allocation[i][j] = Allocation[i][j] + Request[j];
                Need[i][j] = Need[i][j] - Request[j];
                showdata();//根据进程需求量显示安换后的资源
                safe();//根据进程需求量进行最行家算法判断


                //如果不安全拒绝分配
                for (int k = 0; k < N; k++) {
     
                    if (Finish[k] == false) {
     
                        allow = 0;
                        break;
                    }
                }
            }
            if (allow == 0) {
     
                for (int j = 0; j < M; j++) {
     
                    Avaliable[j] = Avaliable[j] + Request[j];
                    Allocation[i][j] = Allocation[i][j] - Request[j];
                    Need[i][j] = Need[i][j] + Request[j];
                }
                System.out.printf("应拒绝P%d的申请,此次尝试分配作废", i);
                System.out.println("");
                System.out.println("还原资源分配矩阵");
                showdata();
            }
        }
    }


    public static void main(String[] args) {
     
        Bank bank = new Bank();
        int[] temp = new int[100];//每种资源已分配的碧重
        Scanner input = new Scanner(System.in);
        System.out.print("系统可用资源种类个数为:");
        int m = input.nextInt();
        bank.M = m;
        for (int i = 0; i < m; i++) {
     
            System.out.printf("资源%d的名称:", i+1);
            bank.Name[i] = input.next();
            System.out.print("资源" + bank.Name[i] + "的初始个数为:");
            int number = input.nextInt();
            bank.Avaliable[i] = number;
        }
        System.out.println("");
        System.out.print("证输入进程数目:");
        int n = input.nextInt();
        bank.N = n;
        System.out.print("请输入各进程的最大需求矩阵的值[Max]:\n");
        for (int i = 0; i < n; i++)
            for (int j = 0; j < m; j++)
                bank.Max[i][j] = input.nextInt();
        do {
     
            boolean flag = false;
            System.out.print("请输入各进程已经分配的资源量[Allocation]:\n");
            for (int i = 0; i < n; i++)
                for (int j = 0; j < m; j++) {
     
                    bank.Allocation[i][j] = input.nextInt();
                    if (bank.Allocation[i][j] > bank.Max[i][j])
                        flag = true;

                    bank.Need[i][j] = bank.Max[i][j] - bank.Allocation[i][j];
                    temp[j] += bank.Allocation[i][j];
                }
            if (flag == true) {
     
                System.out.println("申请的资源大于最大需求量。请置新输入!");
                for (int j = 0; j < m; j++)
                    temp[j] = 0; //清空缓神区
                System.out.println("");
            }
        }while(false);
            for (int j = 0; j < m; j++)
                bank.Avaliable[j] = bank.Avaliable[j] - temp[j];//剩下的可用资源
            bank.showdata();//显示各种资源
            bank.safe();//用银行家算法判定系统是否安全
            while (true) {
     
                System.out.print("**********************************");
                System.out.println("");
                System.out.println("银行家算法:");
                System.out.printf("是否请求分配吗?是请按y/Y,否则请按其它键!\n");
                System.out.println("输入是否请求分配的字符");
                char choice = input.next().charAt(0);
                if (choice == 'y' || choice == 'Y') {
     
                    bank.bank();
                } else break;
            }
        }
    }




结果测试:

Java 实现OS进程安全检测算法之银行家算法(Bankers Algorithm)_第1张图片

Java 实现OS进程安全检测算法之银行家算法(Bankers Algorithm)_第2张图片
Java 实现OS进程安全检测算法之银行家算法(Bankers Algorithm)_第3张图片
Java 实现OS进程安全检测算法之银行家算法(Bankers Algorithm)_第4张图片

Java 实现OS进程安全检测算法之银行家算法(Bankers Algorithm)_第5张图片

你可能感兴趣的:(Java算法,及JDK底层研究,算法,操作系统)