广州大学2021版操作系统实验二——银行家算法(java实现)


前言

对java感兴趣的同学,想用java完成银行家算法,却没有思路,可以参照本人的java版银行家算法,如果某些案例会出错记得在评论区说下错误哦,以防后面的同学以为这是对的。


提示:以下是本篇文章正文内容,下面案例可供参考

一、实验目的

掌握银行家算法思想,并能编程实现。

二、实验内容和要求

1、在Linux环境下编译运行程序;
2、按照教材的算法编写;
3、输入数据从文本文件中读出,不从键盘录入,数据文件格式见以下说明;
4、主要数据结构的变量名和教材中的一致,包括Available、Max、Allocation、Need、Request、Work、Finish。
5、程序可支持不同个数的进程和不同个数的资源;
6、验证教材中的“银行家算法示例”中的例子(包括可成功分配、不可分配)。

三、实验原理

实验原理部分是本人自己写的,大家也可以参照课本写实验原理。

1、在Linux环境下编译运行程序;
2、按照教材的算法编写;
3、输入数据从文本文件中读出,不从键盘录入,数据文件格式见以下说明;
4、主要数据结构的变量名和教材中的一致,包括Available、Max、Allocation、Need、Request、Work、Finish。
5、程序可支持不同个数的进程和不同个数的资源;
6、验证教材中的“银行家算法示例”中的例子(包括可成功分配、不可分配)。

四、实验程序

bookdata.txt文件如下所示:(对课本中的例子进行解释,课本中的例子的Need是还没有进行减掉已经分配的资源)
5 4
3 14 12 12
0 0 1 2 0 0 1 2
1 7 5 0 1 0 0 0
2 3 5 6 1 3 5 4
0 6 5 2 0 6 3 2
0 6 5 6 0 0 1 4
程序代码(注释比较多):

import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class banker {
    private static int MAX_ARR[][];
    private static int ALLOCATION_ARR[][];
    private static int NEED_ARR[][];
    private static int AVAILABLE_ARR[];

    //用来输出当前的序列
    private static List<Integer>SEQ=new ArrayList<Integer>();

    private static int FORK_NUM;
    private static int RESOURCE_NUM;

    public static void main(String[] args) {
        //银行家算法入口
        Bank();
    }

    private static void Bank() {
        boolean inputIsFinish= isInputIsFinish();
        if(inputIsFinish){
            if(calculateAnotherArr()){
                if(initIsSafe(ALLOCATION_ARR,NEED_ARR,AVAILABLE_ARR,FORK_NUM,RESOURCE_NUM)){
                    System.out.println("The init is safe!");
                    System.out.print("The sequence is:");
                    //对序列进行输出
                    outputSEQ();
                    //对用户输入的请求申请和释放进行处理
                    System.out.print("Choose your choice(0:request 1:release)");
                    Scanner scanner=new Scanner(System.in);
                    int choice=scanner.nextInt();
                    switch (choice){
                        case 0:
                            //进行请求资源处理
                            if(requestrelease(true)){
                                System.out.println("The request will be safe!");
                                System.out.print("The sequence is:");
                                outputSEQ();
                            }else{
                                System.out.println("The input will not be safe!");
                            }
                            break;
                        case 1:
                            //进行资源释放处理
                            if(requestrelease(false)){
                                System.out.println("The release will be safe!");
                                System.out.print("The sequence is:");
                                outputSEQ();
                            }else{
                                System.out.println("The input will not be safe!");
                            }
                            break;
                        default:
                            System.out.println("the input not we want");
                            break;
                    }
                }else{
                    System.out.println("The init is not safe!");
                }
            }
        }
    }

    /**
     * 如果参数为true那就说明是request、如果参数为false说明是release
     * 进行资源的请求
     * 用户的输入拆分:第一个输入是第几个进程;第二个输入是第几类资源;第三个输入是数量
     * 1.先判断资源能不能申请成功
     * 1.1条件:①request要小于等于available②request要小于等于need
     * 1.2结果:要对该进程的allocation(+)、need(-)、系统的available(-)进行过更改
     * 2.分配完之后进行判断当前系统是否所有进程都处于安全状态
     * release是将进程的资源进行释放
     * relesase的解释:release是将 进程i的第j类资源释放后给available
     * 条件:release<=allocation
     * 结果allocation(-)、need(+)、available(+)
     * @return
     */
    private static boolean requestrelease(boolean ReqRel) {
        //申请数组大小
        int[][] allocation=new int[FORK_NUM][RESOURCE_NUM];
        int[][] need=new int[FORK_NUM][RESOURCE_NUM];
        int[] work=new int[RESOURCE_NUM];
        //复制数组内容部分
        copy_two_Arr(allocation,ALLOCATION_ARR);
        copy_two_Arr(need,NEED_ARR);
        copy_one_Arr(work,AVAILABLE_ARR);
        //对数组进行输入
        int[]request=inputReql();
        if(ReqRel){
            //Request请求
            if(requestSafe(request,need,work)){
                allocation[request[0]][request[1]]+=request[2];
                need[request[0]][request[1]]-=request[2];
                work[request[1]]-=request[2];
                return initIsSafe(allocation,need,work,FORK_NUM,RESOURCE_NUM);
            }else{
                return false;
            }
        }else{
            //Release请求
            if(releaseSafe(request,allocation)){
                allocation[request[0]][request[1]]-=request[2];
                need[request[0]][request[1]]+=request[2];
                work[request[1]]+=request[2];
                return initIsSafe(allocation,need,work,FORK_NUM,RESOURCE_NUM);
            }else{
                return false;
            }
        }

    }

    /**
     * 如果release超过了allocation,那么就不对
     * @param data
     * @param allocation
     * @return
     */
    private static boolean releaseSafe(int[] data, int[][] allocation) {
        //data[3] 0-进程编号 1-第几种资源 2-资源数量
        if(data[0]>=FORK_NUM||data[1]>=RESOURCE_NUM){
            System.out.println("the fork which you input is out of number of Forks");
            return false;
        }else{
            if(data[2]>allocation[data[0]][data[1]]){
                return false;
            }
        }
        return true;
    }

    /**
     * 用来判断输入的request是否是安全的
     * 条件:①request要小于等于available②request要小于等于need
     * @param data
     * @param need
     * @param available
     * @return
     */
    private static boolean requestSafe(int[] data, int[][] need, int[] available) {
        //data[3] 0-进程编号 1-第几种资源 2-资源数量
        if(data[0]>=FORK_NUM||data[1]>=RESOURCE_NUM){
            System.out.println("the fork which you input is out of number of Forks");
            return false;
        }else{
            if(data[2]>need[data[0]][data[1]]||data[2]>available[data[1]]){
                return false;
            }
        }
        return true;
    }

    /**
     * 用来判断初始状态是否是一个安全状态
     * 或者后续的request
     * @return
     * @param allocationArr
     * @param needArr
     * @param availableArr
     * @param forkNum
     * @param resourceNum
     */
    private static boolean initIsSafe(int[][] allocationArr, int[][] needArr, int[] availableArr, int forkNum, int resourceNum) {
        SEQ.clear();
        //用来记录当前进程是否已经完成分配
        boolean FINISH[]=new boolean[forkNum];
        //对值进行复制,不然修改的时候可能会改变原来AVAILABLE的原始数据
        int available[]=new int[resourceNum];
        copy_one_Arr(available,availableArr);
        for(int i=0;i<forkNum;i++){
            //要执行的趟数
            for(int j=0;j<forkNum;j++){
                boolean isChanged=true;
                //如果当前进程已经完成了分配那么就跳过当前的循环
                if(FINISH[j]) continue;
                //每一趟要执行那么多次
                for(int k=0;k<resourceNum;k++){
                    if(available[k]<needArr[j][k]){
                        isChanged=false;
                        break;
                    }
                }
                if(isChanged){
                    SEQ.add(j);
                    for(int k=0;k<resourceNum;k++){
                        //将当前已经分配完的资源归还给系统
                        available[k]+=allocationArr[j][k];
                    }
                    FINISH[j]=true;
                }
            }
        }
        return allIsFinish(FINISH);
    }

    /**
     * 用来判断所有进程是否都完成分配
     * @param finish
     * @return
     */
    private static boolean allIsFinish(boolean[] finish) {
        boolean ok=true;
        for(int i=0;i<FORK_NUM;i++){
            ok=ok&&finish[i];
        }
        return ok;
    }

    /**
     * 该函数用来执行将文件中的内容赋予banker属性当中
     * 文件的第一行分别表示进程的数目、资源的种类
     * 文件第二行表示资源的数量
     * 文件第三行到末尾 1-RESOURCE列代表的是max
     *               RESOURCE_NUM-2*RESOURCE_NUM列代表的是allocation
     * @return
     */
    private static boolean isInputIsFinish() {
        File file=new File("D:\\code\\linux\\book_data.txt");
        try {
            FileReader fr=new FileReader(file);
            BufferedReader bufr=new BufferedReader(fr);
            //第一行表示进程的数目、资源的种类,对其进行处理
            String line=bufr.readLine();
            String[] line_content=line.split(" ");
            FORK_NUM=Integer.parseInt(line_content[0]);
            RESOURCE_NUM=Integer.parseInt(line_content[1]);
            //第二行表示资源的数量,暂且保存该值,因为后面输入MAX\ALLOCATION的时候还要根据情况修改
            AVAILABLE_ARR=new int[RESOURCE_NUM];
            line=bufr.readLine();
            line_content=line.split(" ");
            for(int i=0;i<RESOURCE_NUM;i++){
                AVAILABLE_ARR[i]=Integer.parseInt(line_content[i]);
            }
            //第三行开始就跟进程有关
            //先对MAX和ALLOCATION进行初始化
            MAX_ARR=new int[FORK_NUM][RESOURCE_NUM];
            ALLOCATION_ARR=new int[FORK_NUM][RESOURCE_NUM];
            int fork_line=0;
            while((line=bufr.readLine())!=null){
                line_content=line.split(" ");
                for(int i=0;i<RESOURCE_NUM;i++){
                    MAX_ARR[fork_line][i]=Integer.parseInt(line_content[i]);
                    ALLOCATION_ARR[fork_line][i]=Integer.parseInt(line_content[i+RESOURCE_NUM]);
                }
                fork_line++;
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            return false;
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }

        return true;
    }

    //----------------------------------下面是功能函数--------------------------------------------------------

    /**
     * 进行测试的函数,里面都装满了测试的内容
     */
    private static void test(){
        //输出成功进行测试
        //测试文件是否传输成功
        System.out.println("--------------MAX--------------------");
        for(int i=0;i<FORK_NUM;i++){
            for(int j=0;j< RESOURCE_NUM;j++){
                System.out.print(MAX_ARR[i][j]+" ");
            }
        }
        System.out.println();
        System.out.println("--------------ALLOCATION--------------------");
        for(int i=0;i<FORK_NUM;i++){
            for(int j=0;j< RESOURCE_NUM;j++){
                System.out.print(ALLOCATION_ARR[i][j]+" ");
            }
        }

        //测试NEED是否输入成功
        System.out.println();
        System.out.println("--------------NEED--------------------");
        for(int i=0;i<FORK_NUM;i++){
            for(int j=0;j< RESOURCE_NUM;j++){
                System.out.print(NEED_ARR[i][j]+" ");
            }
        }

        //测试available是否更改成功
        System.out.println();
        System.out.println("--------------AVAILABLE--------------------");
        for(int j=0;j< RESOURCE_NUM;j++){
            System.out.print(AVAILABLE_ARR[j]+" ");
        }
    }

    /**
     * 对数组进行值复制
     * 一维数组的复制,
     * @param arr
     * @param ARR
     */
    private static void copy_one_Arr(int[] arr, int[] ARR) {
        int size=arr.length;
        for(int i=0;i<size;i++){
            arr[i]=ARR[i];
        }
    }

    /**
     * 该函数用来复制二维数组的值
     * @param arr
     * @param ARR
     */
    private static void copy_two_Arr(int[][] arr, int[][] ARR) {
        for(int i=0;i<FORK_NUM;i++){
            for(int j=0;j<RESOURCE_NUM;j++){
                arr[i][j]=ARR[i][j];
            }
        }
    }

    /**
     * 用来计算其它数组
     * 其中要计算need
     * 计算available,先要计算出所有进程对同一个资源分配了多少资源,用available减去已经分配的资源
     */
    private static boolean calculateAnotherArr() {
        //先计算need
        //先对need进行初始化
        NEED_ARR=new int[FORK_NUM][RESOURCE_NUM];
        for(int i=0;i<FORK_NUM;i++){
            for(int j=0;j<RESOURCE_NUM;j++){
                NEED_ARR[i][j]=MAX_ARR[i][j]-ALLOCATION_ARR[i][j];
            }
        }
        //接下来计算available
        int[] allocation_sum=new int[RESOURCE_NUM];
        //先对所有allocation进行初始化为0,方便后面进行计算
        for(int i=0;i<RESOURCE_NUM;i++){
            allocation_sum[i]=0;
        }
        //计算每一个进程拥有一种资源的数目
        for(int i=0;i<FORK_NUM;i++){
            for(int j=0;j<RESOURCE_NUM;j++){
                allocation_sum[j]+=ALLOCATION_ARR[i][j];
            }
        }
        //用availeble减掉allocation_sum
        for(int i=0;i<RESOURCE_NUM;i++){
            AVAILABLE_ARR[i]-=allocation_sum[i];
        }
        return true;
    }

    /**
     * 该函数用来进行用户从终端输入数据并且存储
     * @return
     */
    private static int[] inputReql() {
        System.out.println("input you want use 空格 to classify");
        Scanner scanner=new Scanner(System.in);
        String line=scanner.nextLine();
        String[] s_data=line.split(" ");
        int[] data=new int[3];
        for(int i=0;i<3;i++){
            data[i]=Integer.parseInt(s_data[i]);
        }
        return data;
    }

    /**
     * 对序列进行输出
     */
    private static void outputSEQ() {
        int size=SEQ.size();
        for(int i=0;i<size;i++){
            if(i!=size-1){
                System.out.print(SEQ.get(i)+"->");
            }else{
                System.out.print(SEQ.get(i));
            }
        }
        System.out.println();
    }
}

五、验证数据和运行结果

程序的说明:首先程序会先进行判断初始状态下是否是安全状态,只有初始状态是安全状态,后面才能够进行资源的申请和释放。
程序进行终端输入的时候记得用空格分开
①验证available能进行试错(因为available可能会超出系统拥有的available),在终端输入1 1 7
在这里插入图片描述

验证成功,能对available可能会超出范围进行试错
②验证need能进行试错,在终端输入2 3 4
在这里插入图片描述

验证成功,能对need超出范围进行试错
③正常输入,按照课本进行输入,
由于课本中规定request(0,4,2,0)所以要分别输入1 1 4 和3 2 2
要对代码进行适当的更改,因为不支持多次输入(按照课本的逻辑)
代码的修改如下
在这里插入图片描述

④使用释放资源,在终端输入2 1 3
在这里插入图片描述

⑤再对释放资源试验,在终端输入4 3 4
在这里插入图片描述

⑥对请求资源进行试验,在终端输入3 2 2
在这里插入图片描述

⑦对请求资源进行试验,在终端输入1 1 5
在这里插入图片描述

以上结果的安全序列都是0 2 3 4 1

现在对book_data进行修改为课本的3个进程共享12个同类资源
在这里插入图片描述
在这里插入图片描述

第一组数据对应的系统安全,安全序列为1 2 0

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

第二组数据对应的系统不安全。

六、代码思路

1.对以上实验的代码进行思维导图设计

在这里插入图片描述
函数名 函数介绍
1.Boolean isInputIsFinish() 用来判断是否从文件中读取数据成功。
对FORK_NUM、RESOURCE_NUM、AVAILABLE_ARR、MAX_ARR进行赋值。
返回是否赋值成功。
2.boolean requestrelease(boolean ReqRel) 用来进行请求资源或者释放资源的操作.
当参数为真说明是请求资源、为假说明是释放资源。
3.boolean releaseSafe(int[] data, int[][] allocation) 用来判断释放是否会超过进程已经分配资源的大小。
4.Data为用户的输入,allocation为已经分配的资源。
5.boolean requestSafe(int[] data, int[][] need, int[] available) 用来判断请求的资源是否会超过进程需要的资源和系统没有被用的资源。
6.boolean initIsSafe(int[][] allocationArr, int[][] needArr, int[] availableArr, int forkNum, int resourceNum) 用来判断系统当前是否处于安全这状态。
7.void test() 用来进行测试,测试是否对max、allocation、need、available进行设置成功
8.void copy_one_Arr(int[] available, int[] availableArr) 用来进行一维数组的值复制,为了防止进行函数传参时对原本的available进行变更
9.void copy_two_Arr(int[][] arr, int[][] ARR) 用来进行二维数组的值复制,为了防止进行函数传参时对原本的need、max、allocation进行变更
10.boolean calculateAnotherArr() 用来给need和available进行赋值
11.int[] inputReql() 处理对用户的输入
12.void outputSEQ() 输出安全序列

七、思考和分析

附:银行家算法的验证数据文件data格式说明

验证数据:建立在程序目录下建立data文件,文件内容是:
5 3
10 5 7
0 0 1 0 7 5 3
1 2 0 0 3 2 2
2 3 0 2 9 0 2
3 2 1 1 2 2 2
4 0 0 2 4 3 3

1 1 0 2
4 3 3 0
0 0 2 0
第一行:5个进程,3种资源。
第二行:每种资源系统拥有的最大数量。
3-7行:第一列是进程号(按顺序排),2-4列是Allocation(资源请求)向量,5-7列是Max(最大资源需求量)向量。
8-10行:第一列是进程号,2-4列是Request(资源请求)向量。

运行程序,通过命令行参数指定文件,如: ./banker ./data运行。

import java.io.*;
import java.util.ArrayList;
import java.util.List;

public class banker {
    public static void main(String[] args) {
        SAFE();
    }

    /**
     * allocation数组,第一个位置用来存放进程的序号
     * MAX数组,必须是进程数目加一,第一个位置用来存放进程的序号
     * 进行初始状态判断是否安全
     * @return
     */
    private static void SAFE() {
        //数据区域
        int FORK_NUM;            //进程数目
        int RESOURCE_NUM;        //资源数目

        int[]AVAILABLE_ARR;                                     //资源拥有的最大数量
        List<int[]> ALLOCATION_ARR=new ArrayList<int[]>();     //allocation数组,第一个位置用来存放进程的序号
        List<int[]>MAX_ARR=new ArrayList<int[]>();             //MAX数组,必须是进程数目加一,第一个位置用来存放进程的序号
        List<int[]>NEED_ARR=new ArrayList<int[]>();            //NEED数组,必须是进程数目加一,第一个位置用来存放进程的序号
        List<int[]>REQUEST_ARR=new ArrayList<int[]>();         //request数组

        //读取文件
        File file=new File("D:\\code\\linux_experiment2\\src\\data.txt");
        try {
            FileReader fr=new FileReader(file);
            BufferedReader bufr=new BufferedReader(fr);
            String file_line;
            file_line=bufr.readLine();
            String[] line=file_line.split(" ");
            FORK_NUM=Integer.parseInt(line[0]);
            RESOURCE_NUM=Integer.parseInt(line[1]);

            //对拥有的资源进行赋值
            AVAILABLE_ARR=new int[RESOURCE_NUM];
            file_line=bufr.readLine();
            line=file_line.split(" ");
            for(int i=0;i<RESOURCE_NUM;i++){
                AVAILABLE_ARR[i] = Integer.parseInt(line[i]);
            }

            //5个进程所以执行五行对max和allocation进行赋值
            for(int num=0;num<FORK_NUM;num++){
                file_line=bufr.readLine();

                //用来初始化max和allocation数组将其压入list当中
                int[] max=new int[RESOURCE_NUM+1];
                int[] allocation=new int[RESOURCE_NUM+1];

                line=file_line.split(" ");

                int seq=Integer.parseInt(line[0]);
                max[0]=seq;
                allocation[0]=seq;
                for(int i=1;i<RESOURCE_NUM+1;i++){
                    allocation[i]=Integer.parseInt(line[i]);
                    max[i]=Integer.parseInt(line[i+RESOURCE_NUM]);
                }
                //赋值完压入list当中
                ALLOCATION_ARR.add(allocation);
                MAX_ARR.add(max);
            }

            //对AVAILABLE进行赋值
            int[] temp=new int[RESOURCE_NUM];
            //初始化
            for(int i=0;i<RESOURCE_NUM;i++){
                temp[i]=0;
            }
            for(int i=0;i<FORK_NUM;i++){
                int[] allocation=ALLOCATION_ARR.get(i);
                for(int j=0;j<RESOURCE_NUM;j++){
                    temp[j]+=allocation[j+1];
                }
            }
            for(int i=0;i<RESOURCE_NUM;i++){
                AVAILABLE_ARR[i]=AVAILABLE_ARR[i]-temp[i];
            }
            //求出need数组
            calNeed(NEED_ARR,ALLOCATION_ARR,MAX_ARR,RESOURCE_NUM,FORK_NUM);
            //对need的最终结果进行测试
//            System.out.println("------NEED-------------");
//            for(int[] s:ALLOCATION_ARR){
//                int size=s.length;
//                for(int i=0;i<size;i++){
//                    System.out.print(s[i]);
//                }
//                System.out.println();
//            }

            //request进行赋值
            inputInList(REQUEST_ARR,bufr,RESOURCE_NUM);

            //用来判断初始化是否是一个安全序列
            System.out.println(initIsSafe(MAX_ARR,ALLOCATION_ARR,NEED_ARR,AVAILABLE_ARR,FORK_NUM,RESOURCE_NUM));

            //判断requesti是否正确
            for(int i=0;i<REQUEST_ARR.size();i++){
                int[] request=REQUEST_ARR.get(i);
                int[] need=NEED_ARR.get(request[0]);                //当前进程的need
                boolean isSafe=true;
                for(int j=1;j<RESOURCE_NUM+1;j++){
                    if(need[j]<request[j]||AVAILABLE_ARR[j-1]<request[j]){
                        isSafe=false;
                        System.out.println("request "+i+" is safe:false");
                        break;
                    }
                }
                if(isSafe)
                    System.out.println("request "+i+" is safe:"+requestIsSafe(MAX_ARR,NEED_ARR,ALLOCATION_ARR,FORK_NUM,RESOURCE_NUM,AVAILABLE_ARR,request));
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 用来判断request是否安全
     * @param max_arr
     * @param need_arr
     * @param allocation_arr
     * @param fork_num
     * @param resource_num
     * @param available_arr
     * @param request
     * @return
     */
    private static boolean requestIsSafe(List<int[]> max_arr, List<int[]> need_arr, List<int[]> allocation_arr, int fork_num, int resource_num, int[] available_arr, int[] request) {
        //将参数当中拥有的内容复制给新的结构,然后使用initIsSafe进行是否安全的判断
        List<int[]>max=copyList(max_arr);
        List<int[]>need=copyList(need_arr);
        List<int[]>allocation=copyList(allocation_arr);
        int[] available=new int[resource_num];
        int[] fork_need_line=need.get(request[0]);
        int[] fork_allocation_line=allocation_arr.get(request[0]);
        int[] fork_max_line=max_arr.get(request[0]);
        for(int i=0;i<resource_num;i++){
            available[i]=available_arr[i]-request[i+1];
            fork_need_line[i+1]-=request[i+1];
            fork_allocation_line[i+1]=fork_max_line[i+1]-fork_need_line[i+1];
        }
        need.set(request[0],fork_need_line);
        allocation.set(request[0],fork_allocation_line);
        return initIsSafe(max,allocation,need,available,fork_num,resource_num);
    }

    /**
     * 对list进行复制
     * @param ARR
     * @return
     */
    private static List<int[]> copyList(List<int[]> ARR) {
        List<int[]>arr=new ArrayList<int[]>();
        for(int i=0;i<ARR.size();i++){
            int[] a=ARR.get(i);
            int[] b=new int[a.length];
            for(int j=0;j<a.length;j++){
                b[j]=a[j];
            }
            arr.add(b);
        }
        return arr;
    }


    /**
     * 将文件当中的内容压入list当中
     * @param Arr
     * @param bufr
     * @param RESOURCE_NUM
     */
    private static void inputInList(List<int[]> Arr, BufferedReader bufr, int RESOURCE_NUM) {
        String file_line= null;
        try {
            while((file_line = bufr.readLine())!=null){
                String[] line=file_line.split(" ");
                int[] arr=new int[RESOURCE_NUM+1];
                for(int i=0;i<RESOURCE_NUM+1;i++){
                    arr[i]=Integer.parseInt(line[i]);
                }
                Arr.add(arr);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 用来判断初始状态是否安全
     * @param MAX_ARR
     * @param ALLOCATION_ARR
     * @param NEED_ARR
     * @param AVAILABLE_ARR
     * @param FORK_NUM
     * @param RESOURCE_NUM
     */
    private static boolean initIsSafe(List<int[]> MAX_ARR, List<int[]> ALLOCATION_ARR, List<int[]> NEED_ARR, int[] AVAILABLE_ARR, int FORK_NUM, int RESOURCE_NUM) {
        int[] WORK=new int[RESOURCE_NUM];
        //将available_arr中的内容传送给WORK
        for(int i=0;i<RESOURCE_NUM;i++){
            WORK[i]=AVAILABLE_ARR[i];
        }

        boolean FINISH[]=new boolean[FORK_NUM];
        for(int i=0;i<FORK_NUM;i++){
            //用来判断当前趟次是否有进行一次更改
            boolean isChange=false;
            //总共执行所有进程的趟数
            for(int j=0;j<FORK_NUM;j++){
                //如果当前进程判断已经是安全的那么就会进行到下一趟
                if(FINISH[j]) continue;
                //每一趟要执行所有进程的数目的次数
                //将执行到当前位置的MAX赋值给max,代表该进程的最大资源
                int[] max=MAX_ARR.get(j);
                //将执行到当前位置的NEED赋值给need,代表该进程需要的资源
                int[] need=NEED_ARR.get(j);
                //将执行到当前位置的ALLOCATION赋值给allocation,代表该进程已分配的资源
                int[] allocation=ALLOCATION_ARR.get(j);
                if(j!=FORK_NUM-1&&forkIsSafe(need,allocation,AVAILABLE_ARR,WORK,RESOURCE_NUM)) {
                    System.out.print(j+"->");
                    isChange=true;
                    FINISH[j]=true;
                    break;
                }else if(j==FORK_NUM-1){
                    System.out.print(j);
                    isChange=true;
                    FINISH[j]=true;
                    break;
                }
            }
            //当前趟次没有进行更改返回假
            if(!isChange) return false;
        }
        System.out.println();
        return true;
    }

    /**
     * 用来判断当前进程是否安全
     * 如果是一开始的available的话是没有前面的进程编号
     * request的话是有一开始的编号
     * 要对以上的情况进行分类
     * @param need
     * @param allocation
     * @param available
     * @param WORK
     * @param resource_num
     * @return
     */
    private static boolean forkIsSafe(int[] need, int[] allocation, int[] available, int[] WORK, int resource_num) {
        if (WORK.length == resource_num) {
            for(int i=1;i<resource_num+1;i++){
                if(need[i]>WORK[i-1])return false;
            }
            for(int i=1;i<resource_num+1;i++){
                WORK[i-1]+=allocation[i];
            }
        }else{
            for(int i=1;i<resource_num+1;i++){
                if(need[i]<WORK[i]||available[i]<WORK[i])return false;
            }
            for(int i=1;i<resource_num+1;i++){

            }
        }

        return true;

    }

    /**
     * NEED数组,必须是进程数目加一,第一个位置用来存放进程的序号
     * 根据MAX-ALLOCATION求出NEED
     * @param NEED_ARR
     * @param ALLOCATION_ARR
     * @param MAX_ARR
     * @param RESOURCE_NUM
     * @param FORK_NUM
     */
    private static void calNeed(List<int[]> NEED_ARR, List<int[]> ALLOCATION_ARR, List<int[]> MAX_ARR, int RESOURCE_NUM, int FORK_NUM) {
        for(int i=0;i<FORK_NUM;i++){
            //拿出进程的编号
            int[] max=MAX_ARR.get(i);
            int[] allocation=ALLOCATION_ARR.get(i);
            int[] need=new int[RESOURCE_NUM+1];
            //对need进行编号的赋值
            need[0]=max[0];
            //求出每一个need的数值
            for(int j=1;j<RESOURCE_NUM+1;j++){
                need[j]=max[j]-allocation[j];
            }
            //将计算出来的need压入list当中
            NEED_ARR.add(need);
        }
    }

}

运行完就是正确答案了
在这里插入图片描述

附录:关于如何在linux中运行java程序

java在linux下运行

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

GZHU_hcc

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值