java实现简单银行家算法

154 阅读4分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第14天,点击查看活动详情

java实现简单银行家算法

java实现简单银行家算法,文中示例代码介绍的非常详细

银行家算法核心

先寻找满足系统当前剩余的资源量(avaliable )>=进程运行所需的资源数的进程(need),再假设这个进程安全校验是成功的,当这个进程运行完毕后,释放资源后,现在系统当前剩余的资源(avaliable)=avaliable+该线程之前已分配的资源(allocation) ,将该节点进程设为处理时忽略进程,再以上条件为前提进行安全校验。 安全校验:一个进程获得资源后,运行完毕,释放之前分配的资源,其他的线程可以继续运行,而不会造成死锁。 这样就会产生回溯。

满足条件: 是否存在一个进程运行所需的资源数<=当前系统剩余的资源数。

查找操作: 先判断回溯的步长(层数)是否等于节点的个数,如果等于说明已经找到了正确路径,返回真给上一层,如果不满足,则看一下此层是否存在满足条件的节点,如果存在,这一该节点为回溯点开始查找操作。如果都不存在,说明上一层的回溯点不是我们要找的节点,返回假给上一层,并回溯回到上一层节点,将忽略标记清楚,换另一个满足条件的节点继续在进行查找操作。

先以一个满足条件的节点进行忽略标记(下一次查找时可忽略此节点),回溯的步长加一,再进行查找操作(下一层)。

题目:

图片.png

初始时,Allocate[i,j]=0,表示初始时没有进程得到任何资源。假定进程对资源的请求序
列为:

Request(1)[M]=(1,0,0);
Request(2)[M]=(2,1,0);
Request(2)[M]=(2,0,1);
Request(3)[M]=(2,1,1);
Request(4)[M]=(0,0,2);
Request(2)[M]=(1,0,1);
Request(1)[M]=(1,0,1);\

请用 Banker 算法判断每一次资源请求是否接受,如果接受请求,请给出请求接受后的资源分配状态,即 Allocate 矩阵、Need 矩阵和 Available 向量。

大致思路:

(1):判断该进程资源请求是否小于Need需求矩阵,小于则进第二步

(2):判断该进程资源请求向量是否小于剩余资源向量Available,小于则进入第三步

(3):备份下资源状态矩阵,假设接收该需求,求出相应的资源状态矩阵,需求矩阵,剩余资源向量

(4):判断接收请求后的状态是否是安全状态
A:初始该状态下的进程标识都为false,work为资源剩余向量

B;循环该状态下的进程,如果满足标识为false,并且该进程的需求向量小于work 则进入C,当循环完毕都没有满足条件的进入D。

C:work+Allocate(对应进程的状态),将该进程对应的进程状态标识为true,将B的循环数变为0,从头开始循环(进入B)
D:循环遍历该状态下的进程标识,如果都为true则判断状态安全,否则判断状态不安全
(5):如果状态是安全的输入该状态下的各个矩阵与向量,如果不安全,则利用刚刚备份的资源状态矩阵,回滚。

运行截图:

图片.png

图片.png

图片.png

图片.png

图片.png

图片.png

package Banker;

    public class Banker {
     public static int N = 4;// 线程个数
     public static int M = 3;// 资源个数
     public static int[] Resource = { 9, 3, 6 };// 资源向量;
     public static int[][] Cliam = { { 3, 2, 2 }, { 6, 1, 3 }, { 3, 1, 4 }, { 4, 2, 2 } };
     public static int[][] Allocate = new int[N][M];
     public static int[][] Need = { { 3, 2, 2 }, { 6, 1, 3 }, { 3, 1, 4 }, { 4, 2, 2 } };
     public static int[] Available = { 9, 3, 6 };
     public int[][] state = new int[N][M];



     public static void main(String args[]) {

         Banker ban = new Banker();
         //请求序列数组,包含第几个请求,那条进程,请求资源向量。
         int[][][] re={{{1},{1,0,0}},{{2},{2,1,0}},{{2},{2,0,1}},{{3},{2,1,1}},{{4},{0,0,2}},{{2},{1,0,1}},{{1},{1,0,1}}};
         for(int j=0;j<re.length;j++){
         /*
         * re[j][1] 请求向量
         * re[j][0][0]-1 第几个进程
         * j第几个请求
         */
         ban.judgeqingqiu(re[j][1], re[j][0][0]-1, j);//输入第几条进程,请求向向量,第几个请求,调用判断是否符合要求函数 
         }


     }


     //判断请求是否符合要求
     public void judgeqingqiu(int[] Request, int i,int j) {
         /*judgementrequest(Request, i)调用函数,判断该进程请求向量是否小于请求矩阵中对应的向量请求资源
         * judgementrequest(Request, i)调用函数,判断该进程请求向量是否小于剩于资源向量
         */
         if (judgementrequest(Request, i) && judgementrequest(Request, i)) {
         distribute(Request,i);//调用假设分配函数,并将分配状态copy出来
         //judgementsafe(Allocate)判断是否是安全状态
         if (judgementsafe(Allocate)) {

         System.out.println("############");
         System.out.println("第"+(j+1)+"个请求"+"进程"+(i+1)+"请求资源被允许");
         printJuzhen("Allocate", Allocate);
         printJuzhen("Need", Need);
         PrintXianglaing("Available", Available);
         } else {
         System.out.println("############");
         System.out.println("第"+(j+1)+"个请求"+"进程"+(i+1)+"请求资源被拒绝");
         erWeiCopy(Allocate, state);
         }
         } else {
         System.out.println("*****************");
         System.out.println("第"+(j+1)+"个请求"+"进程"+(i+1)+"请求资源被拒绝");
         }
     }

     // 假设符合,分配资源,记录下剩余资源
     public void distribute(int[] Request,int i) {

         state = erWeiCopy(state, Allocate);//将资源分配矩阵保留下来,如果不正确方便回滚
         Allocate = addrequest(Allocate, Request, i);//分配后的资源分配矩阵
         Need = reducerequest(Need, Allocate);//分配后的资源需求矩阵
         Available = AvaileReduceRequest(Available, Allocate);//分配后的资源剩余矩阵
     }

     // 判断状态安全函数
     public boolean judgementsafe(int[][] Allocate) {
         int[] work = new int[M];//相当于标记变量,标识进程是否符合,如果符合为true
         work = yiweicopy(work, Available);//将剩余资源响亮copy到work中
         boolean safe = true;//安全状态,默认为true
         Boolean[] finish = { false, false, false, false };//相当于标记变量,标识进程是否符合,如果符合为true,初始值都为false
         //循环遍历该状态中的进程,判断进程的资源需求是否小于剩余资源数
         for (int j = 0; j < N; j++) {
         //进程资源请求是否小于剩余资源work,并且该进程标识为false,
         if (judgementsafeWork(Need[j], work) && finish[j] == false) {
          finish[j] = true;//,将该进程标识为true,改变work
          for (int h = 0; h < M; h++) {
          work[h] = work[h] + Allocate[j][h];
          }
          j = -1;//,将j=0,再次从头遍历查看进程
         }
         }
         /*
         * 当没有进程满足资源请求是否小于剩余资源work,并且该进程标识为false时
         * 遍历状态数组,看是否都为true
         */
         for (int m = 0; m < N; m++) {
         if (finish[m] == false) {
          safe = false;//如果状态数组中有false那么将safe设置为false
         }
         }
         return safe;
     }

     // 判断状态是否安全时进程资源请求是否小于剩余资源work
     public boolean judgementsafeWork(int[] Request, int[] work) {
         for (int k = 0; k < M; k++) {
        // PrintXianglaing("",Request);
         if (Request[k] >work[k]) {
          return false;
         }
         }
         return true;//返回状态

     }


     // 判断该进程请求向量是否小于请求矩阵中对应的向量请求资源
     public boolean judgementrequest(int[] Request, int i) {

         for (int j = 0; j < M; j++) {
         if (Request[j] > Need[i][j]) {
         return false;
         }
         }

         return true;
     }

     // 判断该进程请求向量是否小于剩于资源向量
     public boolean judgementAvali(int[] Request) {
         for (int j = 0; j < M; j++) {
         if (Request[j] >Available[j]) {
         return false;
         }
         }
         return true;

     }

     // 假设分配后修改资源分配矩阵
     public int[][] addrequest(int[][] Allocate, int[] Request, int i) {

         for (int h = 0; h < M; h++) {
         Allocate[i][h] = Allocate[i][h] + Request[h];
         }

         return Allocate;

     }

     // 假设分配后修改资源的需求矩阵
     public int[][] reducerequest(int[][] Need, int[][] state) {
         for (int j = 0; j < N; j++) {
         for (int h = 0; h < M; h++) {
         Need[j][h] = Cliam[j][h] - state[j][h];
         }
         }
         return Need;
     }

     // 假设分配后修改资源剩余矩阵
     public int[] AvaileReduceRequest(int[] Available, int[][] Allocate) {
         Available = yiweicopy(Available, Resource);
         for (int j = 0; j < N; j++) {
         for (int h = 0; h < M; h++) {
         Available[h] = Available[h] - Allocate[j][h];
         }
         }
         return Available;
     }

     // 二维数组拷贝
     public int[][] erWeiCopy(int[][] x1, int[][] y1) {
         for (int j = 0; j < N; j++) {
         for (int h = 0; h < M; h++) {
         x1[j][h] = y1[j][h];
         }
         }
         return x1;
     }

     // 一维数组拷贝
     public int[] yiweicopy(int[] x1, int[] y1) {
         for (int j = 0; j < M; j++) {
         x1[j] = y1[j];
         }
         return x1;
     }

     // 打印向量
     public static void PrintXianglaing(String id, int[] x) {
         System.out.println(id);
         for (int j = 0; j < x.length; j++) {
         System.out.print(x[j] + " ");
         }
         System.out.println("");
     }

     // 打印矩阵
     public static void printJuzhen(String id, int[][] y) {
         System.out.println(id);
         for (int j = 0; j < N; j++) {
         for (int h = 0; h < M; h++) {
         System.out.print(y[j][h] + " ");
         }
         System.out.println();
         }
     }

    }