银行家算法

安全序列原理

银行家算法
需要分配的资源(MAX)
已经分配的资源(Allocation)
还需要分配的资源(Need)
可分配的资源(Available)
线程(T)

只有当全部线程都满足分配,才是安全序列;
如图:可分配的资源(2,3,3)
T4还需资源(2,2,1),(2,2,1)<(2,3,3)进行分配,T4满足后,可分配资源=T4已经分配的资源+上一次可分配的资源=(2,0,4)+(2,3,3)=(4,3,7);

同理,T5还需资源(1,1,0),进行分配,可分配资源=T5已经分配的资源+上一次可分配的资源=(3,1,4)+(4,3,7)=(7,4,11);

T1还需资源(3,4,7),进行分配,可分配资源=T1已经分配的资源+上一次可分配的资源=(2,1,2)+(7,4,11)=(9,5,13);

T2还需资源(1,3,3),进行分配,可分配资源=T2已经分配的资源+上一次可分配的资源=(4,0,2)+(9,5,13)=(13,5,15);

T3还需资源(0,0,6),进行分配,可分配资源=T5已经分配的资源+上一次可分配的资源=(4,0,5)+(13,5,15)=(17,5,20);

所以安全序列为T4 T5 T1 T2 T3 ;
安全序列不唯一

代码实现


import java.util.Scanner;

public class BankerAlgorithm {
    //定义资源
    //可用资源Availiable 一维数组
    private static int[] availiable = new int[]{3,3,2};
    //最大需求量(每个线程最大资源数)
    private static int[][] max = new int[][]{{7,5,3}, {3,2,2}, {9,0,2}, {2,2,2}, {4,3,3}};
    //已分配的资源(每个线程已分配的)
    private static int[][] allocation = new int[][]{{0,1,0}, {2,0,0},{3,0,2},{2,1,1},{0,0,2}};
    //每个线程还需要的资源数
    private static int[][] need = new int[][]{{7,4,3}, {1,2,2}, {6,0,0}, {0,1,1},{4,3,1}};

    private static void showData(){
        System.out.println("线程号    Max      Allocation      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 j=0; j<3; j++){
                System.out.print(max[i][j]+"  ");
            }
            System.out.print("   ");
            for(int j=0; j<3; j++){
                System.out.print(allocation[i][j]+"   ");
            }
            System.out.print(" ");
            for(int j=0; j<3; j++){
                System.out.print(need[i][j]+"  ");
            }
            System.out.println();
        }
    }
    //分配数据  给定线程,给定该线程需要的资源数
    public static boolean allocateData(int threadNum, int[] request){
        //比较需要的资源数与可用资源的大小关系,大于则直接返回,不予分配
        if(!(request[0] <= need[threadNum][0] && request[1] <= need[threadNum][1] && request[2] <= need[threadNum][2])){
            System.out.println("请求的资源超过了所需要的资源数,分配错误");
            return false;
        }
        if(!(request[0] <= availiable[0] && request[1] <= availiable[1] && request[2] <= availiable[2])){
            System.out.println("尚无足够资源分配,必须等待");
            return false;
        }
        //尝试分配资源给请求的线程
        for(int i=0; i<3; i++) {
            //可分配资源-请求资源数量
            availiable[i] = availiable[i] - request[i];
            //已分配资源+请求资源数量
            allocation[threadNum][i] = allocation[threadNum][i] + request[i];
            //还需要资源-请求资源数量
            need[threadNum][i] = need[threadNum][i] - request[i];
            //安全性检查 调用安全性算法 查询剩余资源能否满足剩下的线程执行
        }
        boolean flag = checkSafe();
        if(flag == true){
            System.out.println("能够安全分配");
            return true;
        }else{
            System.out.println("不能够安全分配");
            //恢复预分配的数据
            for(int j=0; j<3; j++){
                availiable[j] = availiable[j]+request[j];
                allocation[threadNum][j] = allocation[threadNum][j]-request[j];
                need[threadNum][j] = need[threadNum][j]+request[j];
            }
            return false;
        }
    }

    //安全性检查
    public static boolean checkSafe(){
        //找一个能够满足的线程,完成执行后去执行下一个线程
        int i = 0;//线程号
        boolean finish[] = new boolean[5]; //表示每个线程是否执行成功的标识
        while(i<5){
            //线程执行成功之后拿到一个属于自己的标识
            if(finish[i] == false && need[i][0] <= availiable[0] && need[i][1] <= availiable[1] && need[i][2] <= availiable[2]){
                System.out.println("可以分配,执行成功的线程为"+i);
                finish[i] = true;
                //分配资源之后当前线程执行成功,释放自己之前拥有的资源
                for(int j=0; j<3; j++){
                    availiable[j] = availiable[j] + allocation[i][j];
                }
                //当前线程执行完,从头开始找一个新的可分配资源能够满足的线程
                i = 0;
            } else{
                i++;
            }
        }
        //判断每个线程的标识,如果标识都是执行成功的标识,则返回true
        for(i=0; i<5; i++){
            if(finish[i] == false){
                //反之返回false
                return false;
            }
        }
        return true;
    }


    public static void main(String[] args) {
        showData();
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入要请求的线程号:");
        int threadNum = scanner.nextInt();
        int request[] = new int[3];
        String[] sources = new String[]{"A", "B", "C"};
        System.out.println("请输入要请求的资源数目:");
        for(int i=0; i<3; i++){
            System.out.println("请输入"+sources[i]+"类资源的数目: ");
            request[i] = scanner.nextInt();
        }
        //请求资源
        allocateData(threadNum, request);


    }
}
银行家算法=-- - 1. 安全状态: 在某时刻系统中所有进程可以排列一个安全序列:{P1,P2,`````Pn},刚称此时,系统是安全的. 所谓安全序列{P1,P2,`````Pn}是指对于P2,都有它所需要剩余资源数量不大于系统掌握的剩余的空间资源与所有Pi(j<i)所占的资源之和. 2.不安全状态可能产生死锁. 目前状态 最大需求 尚需 P1 3 9 6 P2 5 10 5 P3 2 4 2 在每一次进程中申请的资源,判定一下,若实际分配的话,之后系统是否安全. 3.银行家算法的思路: 1),进程一开始向系统提出最大需求量. 2),进程每次提出新的需求(分期贷款)都统计是否超出它事先提出的最大需求量. 3),若正常,则判断该进程所需剩余剩余量(包括本次申请)是否超出系统所掌握的 剩余资源量,若不超出,则分配,否则等待. 4.银行家算法的数据结构. 1),系统剩余资源量A[n],其中A[n]表示第I类资源剩余量. 2),各进程最大需求量,B[m][n],其中B[j][i]表示进程j对i 类资源最大需求. 3),已分配资源量C[m][n],其中C[j][i]表示系统j程已得到的第i资源的数量. 4),剩余需求量.D[m][n],其中D[j][i]对第i资源尚需的数目. 5.银行家算法流程:当某时刻,某进程时,提出新的资源申请,系统作以下操作: 1),判定E[n]是否大于D[j][n],若大于,表示出错. 2),判定E[n]是否大于系统剩余量A[n],若大于,则该进程等待. 3),若以上两步没有问题,尝试分配,即各变量作调整. 4),按照安全性推测算法,判断,分配过后,系统是否安全,若安全,则实际分配,否则,撤消分配,让进程等待. 6."安全性检测"算法 1),先定义两个变量,用来表示推算过程的数据. F[n]=A[n],表示推算过程中,系统中剩余资源量的变化. J[n]=False表示推算过程中各进程是否假设"已完成" 2),流程: 在"剩余"的进程中(在推算)过程中,一些进程假设已完成,查找D[j][n]<=F[n]的进程,找到后令J[j]=True (假设该进程完成),F[n]+D[j][n](该进程所占资源释放),如此循环执行. 若最后,所有的F[n]=True(在推算过程中,所有进程均可以完成),则表示(分配过后)系统是安全的,否则系统是不安全的.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值