首页 > 编程语言 >银行家算法(Java)

银行家算法(Java)

时间:2022-11-23 12:56:15浏览次数:40  
标签:P2 Java int Work Request length 算法 进程 银行家

系统安全状态

安全状态

指系统能按某种进程推进顺序(P1,P2,... ,Pn)未每个进程Pi分配器所需资源,直至满足每个进程对资源的最大需求,使每个进程都可以顺利的完成,此时成(P1,P2,...,Pn)为安全序列,没找到安全序列则说明系统处于不安全状态

只要系统处于安全状态就不会发生死锁,系统处于不安全状态就有可能会发生死锁

举例

假定系统中有三个进程P1、P2、P3,共有12台磁带机。进程P1总共需要10 台磁带机,P2和P3 分别需要 4,9。假定在T0时刻,进程P1、P2、P3 分别已获得 5、2、2台磁带机,则还有三台尚未分配

进程 最大需求 已分配 可用
P1 10 5 3
P2 4 2
P3 9 2

那么T0 时刻系统是安全的,因为还有一个安全序列(P2,P1,P3)【先将两台磁带机分配给P2,P2执行完后释放所有磁带机,还剩下5台,然后全部分配给P1,执行完释放,再分配给P3】,所以我们称T0时刻系统是安全的

如果此时P3想再请求一个磁带机,这时需要考虑如果分配给P3一个磁带机后是否还能处于安全状态,如果不处于安全状态则不会分配给P3。(分配后已分配为 5、2、3,剩余2,如果全部分配给P2执行完释放也智能剩余4台磁带机,而P1还需要5台,P2还需要6台,显然不能完成执行)所以此时系统并不会将磁带机分配给P3,因为这会让系统处于不安全状态

银行家算法

系统资源分配规则
  • 每一个新进程进入系统时,他必须先声明在运行过程中可能需要请求的每种资源类型的最大单元数目,其数目不超过系统所拥有的资源总量
  • 进程请求一组资源时,系统必须首先确定受否有足够的资源分配给该进程
  • 如果有足够的资源分配,还需要计算将这些资源分配后是否会使系统处于不安全状态
  • 只有当系统不会处于安全状态的时候才会将资源分配给进程,否则让进程等待
数据结构
  • 系统可利用资源向量 Available。这时一个含有m个元素的数组,每个元素表示一类可利用的资源数目。初始值为 系统 的所有资源总量
  • 最大需求矩阵 Max。这是一个 n * m 的矩阵,它定义了系统中 n 个进程中每一个进程对 m 类资源的最大需求(对应上表最大需求,只不过这里有 m 类资源,上表只描述一种)
  • 分配矩阵 Allocation。这是一个 n * m 的矩阵,它定义了系统中 n 个进程中每一个进程对 m 类资源的当前分配量(对应上表已分配,只不过这里有 m 类资源,上表只描述一种)
  • 需求矩阵 Need。这是一个 n * m 的矩阵,用以表示 n 个进程中每个进程对 m 类资源完成程序运行还需要的 数量(就是一个需求量 Need满足如后定义 Need = Max - Allocation ),这个矩阵方便计算
银行家算法

用 Request_i 表示进程 i 的请求资源向量,Request_i[j] = K 表示 进程 i 想要请求获取 第 i 类资源 K 个

public  boolean  isRequest(int[] Request_i, int i) throws InterruptedException {
    for(int j = 0; j < Request_i.length; j++)
        if(Request_i[j] > Need[i][j])
            throw new RuntimeException("请求资源数量超过最大需求资源数量");
    for(int j = 0; j < Request_i.length; j++)
        if(Request_i[j] > Available[j]) {
            synchronized(BankerAlgorithm.class) {
                BankerAlgorithm.class.wait();
                return false;
            }
        }
    // 尝试分配资源
    for(int j = 0; j < Request_i.length; j++) {
        Available[j] -= Request_i[j];
        Allocation[i][j] += Request_i[j];
        Need[i][j] -= Request_i[j];
    }
    // 执行安全分析算法,如果安全则正是将资源分配给进程 Pi,以完成本次分配,否则本次的试探分配作废,恢复原来资源分配状态,让进程 Pi 等待
    if(isSafety()){
        System.out.println("安全:可用分配");
        return true;
    }
    else{
        for(int j = 0; j < Request_i.length; j++) {
            Available[j] += Request_i[j];
            Allocation[i][j] -= Request_i[j];
            Need[i][j] += Request_i[j];
        }
        synchronized(BankerAlgorithm.class) {
            BankerAlgorithm.class.wait();
            return false;
        }
    }
}
安全性算法

先预定义向量 Work 和 布尔数组 Finish

Work表示可提供给进程据徐运行所需的各类资源数目 在执行算法之前初始化 Work = Available

当进程 Pi 满足系统资源分配时令 Finish[i] = true

public boolean isSafety(){
    int[] Work = new int[Available.length];
    boolean[] Finish = new boolean[Need.length];
    for(int i = 0; i < Available.length; i++){
        Work[i] = Available[i];
    }
    int unFinished = Finish.length;	// 定义未完成的数量
    int preUnFinished = -1;	// 定义完成一次计算之后
    while(unFinished != 0 && unFinished != preUnFinished){
        preUnFinished = unFinished;
        TASK: for(int i = 0; i < Finish.length; i++){
            /*
                 * 如果该进程未完成,判断是不是所有的 Work[j] >= Need[i][j]
                 * 如果满足则假设执行完该进程,所以我们可用直接让 Work[j] += Need[i][j],
                 * 并标注已完成 Finish[i] = true;
                 * 未完成数量减1 unFinished--
                 */
            if(!Finish[i]){
                for(int j = 0; j < Need[i].length; j++ ){
                    if(Work[j] < Need[i][j]){
                        //有一项不满足则直接跳过循环(因为已经不可能完成该进程)
                        continue TASK;
                    }
                }
                // 如果全部慢则则完成上述
                for(int j = 0; j < Allocation[i].length; j++)
                    Work[j] += Allocation[i][j];
                Finish[i] = true;
                System.out.println(i);
                unFinished--;
            }
        }
        System.out.println("Work: " + Arrays.toString(Work));
        System.out.println("Finished: " + Arrays.toString(Finish));
        System.out.println("unFinished:" + unFinished);
        System.out.println("preUnFinished:" + preUnFinished);
        /*
         * 如果发现程序执行完一周之后并没有减少 unFinished 那么表明找不到安全序列了
         */
    }
    if(unFinished == 0){
        return true;
    }
    else
        return false;
}

标签:P2,Java,int,Work,Request,length,算法,进程,银行家
From: https://www.cnblogs.com/pupilxiao/p/16917922.html

相关文章

  • 一文带你吃透java中的继承
    继承继承的概念面向对象的三大特征:封装性、继承性、多态性。继承是多态的前提,如果没有继承,就没有多态。继承关系当中的特点:1.子类可以拥有父类的“内容”。2.子类......
  • 嵌入式操作系统内核原理和开发(固定内存分配算法)
       固定内存方式是最简单的方法,也是最容易想到的方法。所谓的固定内存,就是所有分配的内存单元都是一致的。不管你申请的内存大小是多少,它都有一个最小的内存。因此,你申......
  • 嵌入式操作系统内核原理和开发(内存分配算法)
       内存分配是操作系统必须面对的一个环节,除非这个系统本身不需要内存安排,所有业务可以通过全局数据和堆栈搞定。内存分配其实不困难,但是由内存引申出来的东西就比较复......
  • 嵌入式操作系统内核原理和开发(基于链表节点的内存分配算法)
      链接节点的内存分配方法,其实就是一种按需分配的内存分配方法。简单一点说,就是你需要多少内存,我就给你多少内存。当然,为了把分配的内存都连起来,我们还需要对分配节点进......
  • 嵌入式操作系统内核原理和开发(最快、最优、最差内存分配算法)
       前面我们说到了基于​​链表的内存分配​​算法。但是之前我们也说过,其实内存分配一般有三个原则,最快、最优和最差。最快比较好理解,就是寻找到合适的节点就立即分配......
  • java8 升级 17 兼容测试 emt4j
    测试兼容性的,emt4j 在readme里download节目,点击下载 https://github.com/adoptium/emt4j /root/emt4j-0.3/bin/analysis.sh-f8-t17-o/home/jdk8to17.h......
  • Java基本数据类型
    1八种数据类型   1、整型:byte、short、int、long2、字符型:char3、浮点型:float、double4、布尔型:boolean 2用法byte(-128~127),8位、有符号的以二进制......
  • 一步一步写算法(之链表排序)
       相比较线性表的排序而言,链表排序的内容稍微麻烦一点。一方面,你要考虑数据插入的步骤;另外一方面你也要对指针有所顾虑。要是有一步的内容错了,那么操作系统会马上给你......
  • 一步一步写算法(之字符串查找 中篇)
       昨天我们编写了简单的字符查找函数。虽然比较简单,但是也算能用。然而,经过我们仔细分析研究一下,这么一个简单的函数还是有改进的空间的。在什么地方改进呢?大家可以慢......
  • 一步一步写算法(之字符串查找 上篇)
       字符串运算是我们开发软件的基本功,其中比较常用的功能有字符串长度的求解、字符串的比较、字符串的拷贝、字符串的upper等等。另外一个经常使用但是却被我们忽视的功......