详解银行家算法「建议收藏」

详解银行家算法「建议收藏」简述:银行家算法是一种可以避免死锁的方法就是以银行借贷系统的分配策略为基础,判断并保证系统的安全运行。我们可以把操作系统看作是银行家,操作系统管理的资源相当于银行家管理的资金,进程向操作系统请求分配资源就相当于用户向银行家贷款。实现方法:为保证资金的安全,银行家规定:(1)当一个顾客对资金的最大需求量不超过银行家现有的资金时就可接纳该顾客;(即当资源池中剩余的可利用资源>=线…

大家好,又见面了,我是你们的朋友全栈君。

简述:银行家算法是一种可以避免死锁的方法

就是以银行借贷系统的分配策略为基础,判断并保证系统的安全运行。我们可以把操作系统看作是银行家,操作系统管理的资源相当于银行家管理的资金,进程向操作系统请求分配资源就相当于用户向银行家贷款。
实现方法:
为保证资金的安全,银行家规定:
(1) 当一个顾客对资金的最大需求量不超过银行家现有的资金时就可接纳该顾客;
(即当资源池中剩余的可利用资源 >= 线程还需要的资源时,就可以将可利用资源分配给此线程)
(2) 顾客可以分期贷款,但贷款的总数不能超过最大需求量;
(线程可以请求分配资源,但是请求的资源总数不能超过资源池中剩余的可利用资源)
(3) 当银行家现有的资金不能满足顾客尚需的贷款数额时,对顾客的贷款可推迟支付,但总能使顾客在有限的时间里得到贷款;
(当线程池中的资源暂时不满足当前的线程所需时,将此线程先暂时搁置,先将资源分配给能够满足的需求的其他线程,等到线程池中的资源足够满足先前搁置的线程时,在将资源分配给搁置的线程)
(4) 当顾客得到所需的全部资金后,一定能在有限的时间里归还所有的资金。
(当线程拿到所需要的所有资源,运行结束后,将自身所有的资源放回资源池中)

实例讲解

下图共有5个线程,4种资源,已经将线程池中的部分资源分配
在这里插入图片描述
分析过程:
资源池中剩余的可用资源量为1 6 2 2,现开始将可用资源量试分配给待运行的线程。
P0已经拥有了0 0 3 2,还需要0 0 1 2,将可以利用的资源量1 6 2 2分配给P0,资源池中就只剩下了1 6 1 0的资源,但P0拥有了0 0 4 4就开始运行,结束后释放自己的所有拥有的资源至资源池中,此时线程池中的总资源量为1 6 5 4,将P0的状态置为true。
P1已经拥有了1 0 0 0,还需要1 7 5 0,接下来本该将资源池中的资源分配给P1,但是经过比较,1 6 5 4 < 1 7 5 0,资源池中的资源不够分给P1,所以先将P1搁置,状态置为false
P2已经拥有了1 3 5 4,还需要2 3 5 6,接下来本该将资源池中的资源分配给P2,但是经过比较,1 6 5 4 < 2 3 5 6,资源池中的资源不够分给P2,所以先将P2搁置,状态置为false
P3已经拥有了0 3 3 2,还需要0 6 5 2,将可以利用的资源量1 6 5 4分配给P3,资源池中就只剩下了1 0 0 2的资源,但P3拥有了0 9 8 4就开始运行,结束后释放自己的所有拥有的资源至资源池中,此时线程池中的总资源量为1 9 8 6,将P3的状态置为true。
P4已经拥有了0 0 1 4,还需要0 6 5 6,将可以利用的资源量1 9 8 6分配给P4,资源池中就只剩下了1 3 3 0的资源,但P4拥有了0 6 6 10就开始运行,结束后释放自己的所有拥有的资源至资源池中,此时线程池中的总资源量为1 9 9 10,将P4的状态置为true。
然后回到搁置的线程处,重新试着分配。 详解银行家算法「建议收藏」
第二个问题如下图:
在这里插入图片描述
代码实现:
实现过程中当部分线程资源得不到满足被暂时搁置后,要等到它的下一个线程状态置true时,从头开始再次进行试分配。

import java.util.Scanner;
public class Banker { 
   
    int available[] = new int[]{ 
   3,3,2};//可得到的资源
    int max[][] = new int[][]{ 
   { 
   7,5,3},{ 
   3,2,2},{ 
   9,0,2},{ 
   2,2,2},{ 
   4,3,3}};//每个进程最大资源数
    int allocation[][] = new int[][]{ 
   { 
   0,1,0},{ 
   2,0,0},{ 
   3,0,2},{ 
   2,1,1},{ 
   0,0,2}};//每个进程目前拥有的资源数
    int need[][] = new int[][]{ 
   { 
   7,4,3},{ 
   1,2,2},{ 
   6,0,0},{ 
   0,1,1},{ 
   4,3,1}};//每个进程需要的资源数
    void showData() { 
   
    //展示数据输出每个进程的相关数
        System.out.println("进程号 Max All Need ");
        System.out.println(" A B C A B C A B C");
        for(int i = 0;i<5;i++){ 
   
            System.out.print(i+" ");
            for(int m = 0;m<3;m++) System.out.print(max[i][m]+" ");
            for(int m = 0;m<3;m++) System.out.print(allocation[i][m]+" ");
            for(int m = 0;m<3;m++) System.out.print(need[i][m]+" ");
            System.out.println();
        }
    }

    boolean change(int inRequestNum,int inRequest[])//分配数据
    { 
   
        int requestNum = inRequestNum;
        int request[] = inRequest;
        // for(int i=0;i<3;i++)System.out.println("修改前available"+available[i]);
        if(!(request[0]<=need[requestNum][0]&&request[1]<=need[requestNum][1]&&request[2]<=need[requestNum][2]))
        { 
   
            //request[0]<=need[requestNum][0]
            //request[1]<=need[requestNum][1]
            //request[2]<=need[requestNum][2]
            //每一类请求资源小于当前线程need的资源数
            System.out.println("请求的资源数超过了所需要的最大值,分配错误");
            return false;
        }
        if((request[0]<=available[0]&&request[1]<=available[1]&&request[2]<=available[2])==false)
        { 
   
            //当前线程的每一类请求资源小于等于资源池对应资源的数量
            System.out.println("尚无足够资源分配,必须等待");
            return false;
        }

        for(int i = 0;i<3;i++)//试分配数据给请求的线程
        { 
   
            available[i] = available[i]-request[i];
            //资源池的每类资源减去每类请求资源数量
            allocation[requestNum][i] = allocation[requestNum][i] + request[i];
            //当前线程allocation中每类资源加上每类资源请求数量
            need[requestNum][i] = need[requestNum][i] - request[i];
            //当前线程need中每类资源数量减去每类资源的请求数量
        }
// for(int i=0;i<3;i++)System.out.println("修改后available"+available[i]);
        boolean flag = checkSafe(available[0],available[1],available[2]);//进行安全性检查并返回是否安全
// System.out.println("安全性检查后"+flag);
        if(flag==true)
        { 
   
            System.out.println("能够安全分配");
            return true;
        }
        else//不能通过安全性检查 恢复到未分配前的数据
        { 
   
            System.out.println("不能够安全分配");
            for(int i = 0;i<3;i++)
            { 
   
                available[i] = available[i]+request[i];
                allocation[requestNum][i] = allocation[requestNum][i] - request[i];
                need[requestNum][i] = need[requestNum][i] + request[i];
            }
            return false;
        }
    }
    boolean checkSafe(int a,int b,int c)//安全性检查
    { 
   
        int work[] = new int[3];
        work[0] = a;
        work[1] = b;
        work[2] = c;
        int i=0;
        boolean finish[] = new boolean[5];
        while(i<5)//寻找一个能够满足的认为完成后才去执行下一进程
        { 
   
            if(finish[i]==false&&need[i][0]<=work[0]&&need[i][1]<=work[1]&&need[i][2]<=work[2])
            { 
   //找到满足的修改work值,然后i=0,重新从开始的为分配的中寻找
                System.out.println("分配成功的是"+i);
                for(int m = 0;m<3;m++)
                    work[m] =work[m] + allocation[i][m];
                finish[i] = true;
                i=0;
            }
            else//如果没有找到直接i++
                i++;
        }
        for(i=0;i<5;i++)//通过finish数组判断是否都可以分配
        { 
   
            if(finish[i]==false)
                return false;
        }
        return true;
    }
    public static void main(String[] args)
    { 
   
        Banker bank = new Banker();
        bank.showData();
        //请求线程资源存放的数组
        int request[] =new int[3];
        int requestNum;
        String source[] = new String[]{ 
   "A","B","C"};
        Scanner s = new Scanner(System.in);
        String choice = new String();
        while(true)//循环进行分配
        { 
   
            System.out.println("请输入要请求的进程号(0--4):");
            requestNum = s.nextInt();
            System.out.print("请输入请求的资源数目");
            for(int i = 0;i<3;i++)
            { 
   
                System.out.println(source[i]+"资源的数目:");
                request[i] = s.nextInt();
            }
            bank.change(requestNum, request);
            System.out.println("是否再请求分配(y/n)");
            choice = s.next();
            if(choice.equals("n"))
                break;
        }
    }
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/163227.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • SPPnet

    SPPnet目录1.Motivation2.SPPnet2.1SPP层的原理2.2SPPnet的区域映射原理3.总结论文:SpatialPyramidPoolinginDeepConvolutionalNetworksforVisualRecognition.来源:ECCV20141.MotivationR-CNN模型存在很多缺点和可改进的地方,其中的两个缺点如下:CNN网络后面接的FC层需要固定的输入大小,导致CNN也需要固定大小的输入,即要求候选区域在进入CNN前需要c

  • 【C语言】求最小公倍数和最大公约数(辗转相除法)

    【C语言】求最小公倍数和最大公约数(辗转相除法)用到的名词:最小公倍数,最大公约数,辗转相除法一、名词解释:1).最小公倍数:最小公倍数(LeastCommonMultiple,LCM),如果有一个自然数a能被自然数b整除,则称a为b的倍数,b为a的约数,对于两个整数来说,指该两数共有倍数中最小的一个。计算最小公倍数时,通常会借助最大公约数来辅助计算。 最小公倍数=两数的乘积/最大公约(因)数,解题时要避免和最大公约(因)…

  • 百度PCS快速获取access_token的方法

    百度PCS快速获取access_token的方法

  • 国内做得好的hr系统_平安hrx下载

    国内做得好的hr系统_平安hrx下载HR专家训练营-X版本成为HR专家系列(X版本)链接:https://pan.baidu.com/s/1–jD9mySf2dIcGKEG-4LYw提取码:8boq备用链接天翼云盘下载不限速,建议使用天翼云下载速度会更快一些https://cloud.189.cn/t/ua2MfmQN7Bnq(访问码:6p4z){1}–课程简介{10}–干部管理{11}–企业文化{1…

  • 将图片转成线稿图_图片怎么转成线稿

    将图片转成线稿图_图片怎么转成线稿1、首先找一张图片,在PS中打开,我随便找了一张自己收藏的壁纸如下图:2、打开图片之后, 我们先把图像处理成黑白。点击菜单栏:图像-调整-黑白。快捷键:Alt+Shitf+Ctrl+B

  • bt3硬盘安装_SD卡比U盘音质好

    bt3硬盘安装_SD卡比U盘音质好在U盘/SD卡上安装BT3教程(激活成功教程无线路由信号密码必备)其实网上关于BT3的教程很多,如果大家根据下面的教程安装不成功的话,可以再去百度一下其它的教程。前几天写过一个帖子是关于如何用BT3激活成功教程路由信号的(点我查看),为了引起关注,放在了Win区。在那个帖子里我是将

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号