使用java实现银行家算法

银行家算法核心

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

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

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

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

import java.util.Arrays;

public class BanksTest {
  // 用于存储预操作后的资源变化
  static int[] new_Avaliable = null;
  // 用于存储预操作的完成度
  static boolean[] new_finish = null;
  // 用于保存最终的进程执行顺序,初始化为非法进程-1
  static int right[] = { -1, -1, -1, -1, -1 };

  public static void main(String[] args) {
    // 最大需求量
    int[][] max = { { 7, 5, 3 }, { 3, 2, 2 }, { 9, 0, 2 }, { 2, 2, 2 }, { 4, 3, 3 } };
    // 当前系统可用资源量
    int[] avaliable = { 3, 3, 2 };
    // 每个进程运行还需资源量
    int[][] need = new int[5][3];
    // 每个进程已分配的资源量
    int[][] allocation = { { 0, 1, 0 }, { 2, 0, 0 }, { 3, 0, 2 }, { 2, 1, 1 }, { 0, 0, 2 } };
    // 用于第一深度预判的初始化
    boolean finish[] = { false, false, false, false, false };
    // 获取每个进程运行时还需的资源量
    for (int i = 0; i < max.length; i++) {
      for (int j = 0; j < max[i].length; j++) {
        need[i][j] = max[i][j] - allocation [i][j];
      }
    }
    // 创建递归深度
    int deep = 0;
    // 调用回溯递归算法
    deepCheck(avaliable, allocation, need, finish, deep, right);
    int i = 0;
    // 查看最终的安全序列的值,看是否存在初始的非法进程,如果存在,则说明该案例不存在安全的进程执行顺序
    for (; i < right.length; i++) {
      if (right[i] == -1) {
        break;
      }
    }
    if (i < right.length) {
      System.out.println("该案例不存在安全的进程执行顺序");
      return;
    }
    // 打印安全的执行顺序
    for (int j = 0; j < right.length; j++) {
      System.out.println(right[j]);

    }

  }

  // 完全递归回溯查找安全顺序
  public static boolean deepCheck(int[] avaliable, int[][] allocation, int[][] need, boolean finish[], int deep,
      int right[]) {
    int j = 0;
    boolean flog = false;
    // 如果深度为进程的个数数说明已经查找到头了,说明上一深度的进程是安全节点。因为上一深度的进程满足了当前资源数大于或等于该进程运行所需的资源数,且为安全序列中最后一个节点。
    if (deep == need.length) {
      return true;
    }
    // 遍历所有节点进程开始查找,直到找到安全校验成功的的节点进程
    for (int i = 0; i < need.length; i++) {
      // 对于未被标记的进行校验,已被标记的为已被列为安全节点所以无需再进行校验
      if (!finish[i]) {
        // 判断当前的节点进程的剩余的资源量,是否满足运行所需的资源量
        for (j = 0; j < avaliable.length; j++) {
          // 不满足
          if (need[i][j] > avaliable[j]) {
            break;
          }
        }
        // 不满足则处理下一个节点进程
        if (j < avaliable.length) {
          continue;
        } else {
          // 满足情况
          // 复制会被修改的前提条件,已便于当前进程校验不成功时,可以恢复前提条件,开始下一个节点进程的校验
          new_Avaliable = Arrays.copyOf(avaliable, avaliable.length);
          new_finish = Arrays.copyOf(finish, finish.length);
          // 假设当前节点进程是可以校验成功的节点进程,修改该进程运行完毕后释放之前分配的进程。
          for (j = 0; j < new_Avaliable.length; j++) {
            new_Avaliable[j] += allocation[i][j];
          }
          // 假设标记当前为校验成功的安全节点进程,下一深度查找时会忽略此进程。
          new_finish[i] = true;
          // 增加深度
          deep++;
          // 以上假设为前提,进行下一深度的安全校验判断其他所剩余进程是否可以继续运行,而不造成死锁。
          flog = deepCheck(new_Avaliable, allocation, need, new_finish, deep, right);
          // 如果进行安全校验后为真,说明当前进程是我们要找的进程
          if (flog) {
            // 保存到最终进程执行序列的数组中
            right[--deep] = i;
            break;
          }

        }

      }

    }
    // 安全校验成功
    if (flog) {
      return true;
    } else {
      // 安全校验失败
      // 清楚之前的假设标记
      new_finish[right[--deep]] = false;
      return false;
    }

  }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • java实现简单银行家算法

    本文实例为大家分享了java实现银行家算法的具体代码,供大家参考,具体内容如下 题目: 初始时,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

  • java实现银行家算法(Swing界面)

    java代码实现了银行家算法,界面写的个人认为还是较为细致的,完整的实现了找安全序列等算法功能,可作为参考学习银行家算法. 直接上代码:①界面展示方法: public void ShowFrame() { this.setSize(500, 350); //大小 this.setAlwaysOnTop(true); this.setResizable(false);//不可拖动 this.setLayout(new BorderLayout()); this.setTitle("lly_bank

  • java实现银行家算法

    本文实例为大家分享了java实现银行家算法的具体代码,供大家参考,具体内容如下 import java.util.Arrays; import javax.swing.JOptionPane; public class Banker_Dijkstra { static int available[]={3,3,2}; //可利用资源数 static int max[][]={{7,5,3},{3,2,2},{9,0,2},{2,2,2},{4,3,3}};; //每线程最大需求 static i

  • 使用java实现银行家算法

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

  • java数据结构与算法之双向循环队列的数组实现方法

    本文实例讲述了java数据结构与算法之双向循环队列的数组实现方法.分享给大家供大家参考,具体如下: 需要说明的是此算法我并没有测试过,这里给出的相当于伪代码的算法思想,所以只能用来作为参考! package source; public class Deque { private int maxSize; private int left; private int right; private int nItems; private long[] myDeque; //constructor p

  • java数据结构与算法之快速排序详解

    本文实例讲述了java数据结构与算法之快速排序.分享给大家供大家参考,具体如下: 交换类排序的另一个方法,即快速排序. 快速排序:改变了冒泡排序中一次交换仅能消除一个逆序的局限性,是冒泡排序的一种改进:实现了一次交换可消除多个逆序.通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列. 步骤: 1.从数列中挑出一个元素,称为 "基准"(piv

  • java数据结构排序算法之树形选择排序详解

    本文实例讲述了java数据结构排序算法之树形选择排序.分享给大家供大家参考,具体如下: 这里我们就来说说选择类排序之一的排序:树形选择排序 在简单选择排序中,每次的比较都没有用到上次比较的结果,所以比较操作的时间复杂度是O(N^2),想要降低比较的次数,则需要把比较过程中的大小关系保存下来.树形选择排序是对简单选择排序的改进. 树形选择排序:又称锦标赛排序(Tournament Sort),是一种按照锦标赛的思想进行选择排序的方法.首先对n个记录的关键字进行两两比较,然后在n/2个较小者之间再进

  • java实现Fibonacci算法实例

    本文实例讲述了java实现Fibonacci算法的方法.分享给大家供大家参考.具体如下: package com.yenange.test2; import java.util.Scanner; public class Fibonacci { private static Scanner input = new Scanner(System.in); public static void main(String[] args) { System.out.println("-----------

  • Java TreeMap排序算法实例

    本文实例讲述了Java TreeMap排序算法.分享给大家供大家参考,具体如下: TreeMap 和 HashMap 用法大致相同,但实际需求中,我们需要把一些数据进行排序: 以前在项目中,从数据库查询出来的数据放在List中,顺序都还是对的,但放在HashMap中,顺序就完全乱了. 为了处理排序的问题: 1. 对于一些简单的排序,如:数字,英文字母等 TreeMap hm = new TreeMap<String, String>(new Comparator() { public int

  • Java抽奖抢购算法

    本文示例为大家分享了Java抽奖抢购算法,供大家参考,具体内容如下 应用场景 单件奖品抢购(可限时) 多件奖品按概率中奖(可限时.可不限量) 代码实现 表结构: --抽奖设置 create table AWARD_INFO ( ID NUMBER(11) not null, ACT_ID NUMBER(11), --活动ID NUM NUMBER(11), --奖品总量(0为不限量) REST NUMBER(11), --奖品余量 ODDS NUMBER(11) default 0, --中奖概

随机推荐