操作系统-银行家算法(安全性算法)进程死锁检测

操作系统-银行家算法(安全性算法)进程死锁检测

import java.util.Scanner;

public class bank {
    private final int M = 3;                    //资源数量
    private final int N = 5;                    //进程数量
    private final int num = 97;   //支持小写字母的进程号,如果是大写字母例如:ABCD进程,则将num改成65,数字的话就改为48

    public void output(int[][] iMax, int[][] iAllocation, int[][] iNeed, int[] iAvailable, char[] cName) {
        int i, j;
        System.out.println("\n\t   Max  \tAllocation\t  Need  \t Available");
        System.out.println("\tA   B   C\tA   B   C\tA   B   C\t A   B   C");
        for (i = 0; i < N; i++) {
            System.out.print(cName[i] + "\t");

            for (j = 0; j < M; j++)
                System.out.print(iMax[i][j] + "   ");
            // System.out.print("\t");

            for (j = 0; j < M; j++)
                System.out.print(iAllocation[i][j] + "   ");
            // System.out.print("\t");

            for (j = 0; j < M; j++)
                System.out.print(iNeed[i][j] + "   ");
            // System.out.print("\t");
            System.out.print(" ");

            //Available只需要输出一次
            if (i == 0)
                for (j = 0; j < M; j++)
                    System.out.print(iAvailable[j] + "   ");
            System.out.println("");
        }

    }

    public boolean safety(int[][] iAllocation, int[][] iNeed, int[] iAvailable, char[] cName) {
        int work[] = new int[M];
        for (int i = 0; i < M; i++) {
            work[i] = iAvailable[i];
        }

        boolean Finish[] = new boolean[N];
        for (boolean x : Finish) {                            //初始化Finish
            x = false;
        }
        int count = N;
        while (count <= N) {
            for (int i = 0; i < N; i++) {
                if (!Finish[i]) {
                    for (int j = 0; j < M; j++) {
                        if (iNeed[i][j] <= work[j]) {
                            Finish[i] = true;
                        } else {
                            Finish[i] = false;
                            break;
                        }
                    }
                    if (Finish[i]) {
                        for (int k = 0; k < M; k++)
                            work[k] = work[k] + iAllocation[i][k];
                        i = -1;
                    }
                }
            }
            for (int k = 0; k < N; k++) {
                if (!Finish[k]) {
                    return false;
                }
            }
            System.out.println("");
            count++;

        }

        //
        return true;
    }

    public boolean banker(int[][] iAllocation, int[][] iNeed, int[] iAvailable, char[] cName) {
        Scanner in = new Scanner(System.in);

        int[] request = new int[N];

        System.out.println("可用的资源数量如下");
        for (int i = 0; i < M; i++) {
            System.out.print(i + ":" + iAvailable[i] + "  ");
        }
        char process_char = '0';                        //进程号
        System.out.println("请输入进程号,可用的进程号如下");
        for (int j = 0; j < N; j++) {
            System.out.print(cName[j] + "  ");
        }
        System.out.println("");
        //------------------------------------------------判断输入的正确性
        boolean flag = true;
        while (flag)                            //判断输入是否正确
        {
            int j = 0;
            process_char = (in.next().toCharArray())[0];
            for (j = 0; j < N; j++) {
                if (process_char == cName[j]) {
                    flag = false;
                    break;
                }
            }

            if ((j >= N - 1) && flag)
                System.out.println("输入有误请重新输入");
        }
        int process = process_char -num;             //将字母的进程号转为数字
        System.out.println("所选进程为" + process);
        System.out.println("请输入请求的资源数");
//---------------------------------------------------判断输入的正确性
        for (int i = 0; i < M; i++) {
            boolean inputFlag=true;
            String c = in.next();
            for (int m = 0; m < c.length(); m++) {
                if (!Character.isDigit(c.charAt(m))) {
                    System.out.println("输入有误请重新输入");
                    i = -1;
                    inputFlag=false;
                    break;
                }
            }
            if(inputFlag)
            {
                request[i]=Integer.parseInt(c);
            }

        }
        //----------------------------------------------------------------银行家算法检测
        for (int i = 0; i < M; i++) {
            if (request[i] > iNeed[process][i])                        //如果需求量小于最大需求数则退回
            {
                System.out.println("请求量超过该进程的资源最大需求量");
                return false;
            }
            if (request[i] > iAvailable[i])                    //如果请求量大于系统目前的资源数,则退回
            {
                System.out.println("请求量超过系统的目前的可用资源总数");
                return false;
            }
        }
        for (int i = 0; i < M; i++)                        //试分配
        {
            iAvailable[i] = iAvailable[i] - request[i];
            iAllocation[process][i] = iAllocation[process][i] + request[i];
            iNeed[process][i] = iNeed[process][i] - request[i];
        }
        boolean flag2 = true;
        flag2 = safety(iAllocation, iNeed, iAvailable, cName);
        if (!flag2)                            //如果安全行算法检验成功
        {
            System.out.println("可能造成死锁");
            for (int i = 0; i < M; i++)                        //还原
            {
                iAvailable[i] = iAvailable[i] + request[i];
                iAllocation[process][i] = iAllocation[process][i] - request[i];
                iNeed[process][i] = iNeed[process][i] + request[i];
            }
            return false;
        }
        System.out.println("请求成功");
        return true;
    }


    public void bank_execute() {
        int i, j;
        //当前可用每类资源的资源数
        int[] iAvailable = {3, 3, 2};

        //系统中N个进程中的每一个进程对M类资源的最大需求
        int[][] iMax = {{7, 5, 3}, {3, 2, 2}, {9, 0, 2}, {2, 2, 2}, {4, 3, 3}};

        //iNeed[N][M]每一个进程尚需的各类资源数
        //iAllocation[N][M]为系统中每一类资源当前已分配给每一进程的资源数
        int[][] iNeed = new int[N][M];
        int[][] iAllocation = {{0, 1, 1}, {2, 0, 0}, {3, 0, 2}, {2, 1, 1}, {0, 0, 2}};
        //进程名
        char[] cName = {'a', 'b', 'c', 'd', 'e'};

        boolean bExitFlag = true;   //退出标记
        String ch;               //接收选择是否继续提出申请时传进来的值

        boolean bSafe;   //存放安全与否的标志
        //计算iNeed[N][M]的值
        for (i = 0; i < N; i++)
            for (j = 0; j < M; j++)
                iNeed[i][j] = iMax[i][j] - iAllocation[i][j];

        output(iMax, iAllocation, iNeed, iAvailable, cName);
        bSafe = banker(iAllocation, iNeed, iAvailable, cName);
        //是否继续
        while (bExitFlag) {
            System.out.println("继续提出申请?y为是;n为否");
            Scanner in = new Scanner(System.in);
            ch = in.next();

            switch (ch) {
                case "y":
                    bSafe = banker(iAllocation, iNeed, iAvailable, cName);
                    if (bSafe)   //安全,则输出变化后的数据
                        output(iMax, iAllocation, iNeed, iAvailable, cName);
                    break;
                case "no":
                    System.out.println("退出");
                    ;
                    bExitFlag = false;
                    break;
                default:
                    System.out.println("输入有误,请重新输入:");
            }
        }


    }

    public static void main(String[] args) {
        new bank().bank_execute();
    }
}

public void output(int[][] iMax, int[][] iAllocation, int[][] iNeed, int[] iAvailable, char[] cName) 方法是将进程,资源信息输出。
注意开头注释中的内容(即进程号是用什么表示的,字母还是数字)。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值