java银行家算法和安全检测算法

问题:

        假设某银行有可借免息工程资助款项共10亿,现有三个工程队分别名为A队、B队、C队。每个工程队各要完成一个需5亿金额的项目,各队皆无分文,需从银行借款以完成各自的项目。各队每次从银行借部分款项以完成项目的一部分,多次借款借足所需5亿后,其项目即可顺利完工,然后再向银行归还所借5亿款项。请用银行家算法来实现上述过程,每个工程队由一线程来模拟,各队每次借款金额由一随机数来产生。

银行家算法中的数据结构:

        (1) 可利用资源向量Available。这是一个含有m个元素的数组,其中的每一个元素代表一类可利用的资源数目,其初始值是系统中所配置的该类全部可用资源的数目,其数值随该类资源的分配和回收而动态地改变。如果Available[j]=K,则表示系统中现有Rj类资源K个。

       (2) 最大需求矩阵Max。这是一个n×m的矩阵,它定义了系统中n个进程中的每一个进程对m类资源的最大需求。如果Max[i,j]=K,则表示进程i需要Rj类资源的最大数目为K。

       (3) 分配矩阵Allocation。这也是一个n×m的矩阵,它定义了系统中每一类资源当前已分配给每一进程的资源数。如果Allocation[i,j]=K,则表示进程i当前已分得Rj类资源的数目为K。

       (4) 需求矩阵Need。这也是一个n×m的矩阵,用以表示每一个进程尚需的各类资源数。如果Need[i,j]=K,则表示进程i还需要Rj类资源K个,方能完成其任务。  

       银行家算法:

      设Requesti是进程Pi的请求向量,如果Requesti[j]=K,表示进程Pi需要K个Rj类型的资源。当Pi发出资源请求后,系统按下述步骤进行检查:

       (1) 如果Requesti[j]≤Need[i,j],便转向步骤2;否则认为出错,因为它所需要的资源数已超过它所宣布的最大值。                 (2) 如果Requesti[j]≤Available[j],便转向步骤(3);否则, 表示尚无足够资源,Pi须等待。

       (3) 系统试探着把资源分配给进程Pi,并修改下面数据结构中的数值:   Available[j]∶=Available[j]-Requesti[j];   Allocation[i,j]∶=Allocation[i,j]+Requesti[j];   Need[i,j]∶=Need[i,j]-Requesti[j];

       (4) 系统执行安全性算法,检查此次资源分配后,系统是否处于安全状态。若安全,才正式将资源分配给进程Pi,以完成本次分配;否则, 将本次的试探分配作废,恢复原来的资源分配状态,让进程Pi等待。

       代码流程图:

       代码:

Bank:

package bank;

public class Bank {
    private double available;       //可利用资源向量
    private double[] max;           //最大需求矩阵,max[i]=K表示进程i需要的最大资源数目为K
    private double[] allocation;    //分配矩阵,allocation[i]=K表示进程i当前已分得资源数为K
    private double[] need;          //需求矩阵,need[i]=K表示进程i还需要K资源才能完成任务
    public Bank(double available, int len, double perNeed){
        //初始化
        this.available = available;
        max = new double[len];
        allocation = new double[len];
        need = new double[len];
        for(int i=0; i<len; i++){
            max[i] = perNeed;
            allocation[i] = 0;
            need[i] = perNeed;
        }
    }
    public synchronized void request(double request, int i) throws InterruptedException {
        boolean safe;
        if(request<=need[i]){
            if(request<=available){
                available = available-request;
                allocation[i] = allocation[i]+request;
                need[i] = need[i]-request;
                if(!testSafe()){
                    need[i] = need[i]+request;
                    allocation[i] = allocation[i]-request;
                    available = available+request;
                    System.out.println(i+"号在等待");
                    this.wait();
                }
            }else {
                System.out.println(i+"号在等待");
                this.wait();
            }
        }else {
            System.out.println("出错");
        }
    }

    public synchronized void back(double money){
        available = available+money;
        System.out.println("收到还钱");
        this.notifyAll();
    }

    private boolean testSafe() {
        for(int i=0; i<max.length; i++){
            if(need[i]<available){
                return true;
            }
        }
        return false;
    }
}

Start:

package bank;

public class Start {
    public static void main(String[] args){
        Semaphore semaphore = new Semaphore(1);
        double need = 5;
        int len = 3;
        Team[] teams = new Team[3];
        Bank bank = new Bank(10, len, need);
        teams[0] = new Team("A",5,semaphore, bank, 0);
        teams[1] = new Team("B",5,semaphore, bank, 1);
        teams[2] = new Team("C",5,semaphore, bank, 2);

        new Thread(teams[0]).start();
        new Thread(teams[1]).start();
        new Thread(teams[2]).start();
    }
}

Team:

package bank;

import java.text.DecimalFormat;
import java.util.Random;

public class Team implements Runnable{
    private String teamName;
    private double count;
    private double need;    //需要资源的总数
    private Semaphore semaphore;
    private Bank bank;
    private int number;

    public Team(String teamName, double count, Semaphore semaphore, Bank bank, int number) {
        this.teamName = teamName;
        this.count = count;
        this.need = count;
        this.semaphore = semaphore;
        this.bank = bank;
        this.number = number;
    }
    public double getNeed(){
        return this.need;
    }
    @Override
    public void run() {
        Random random = new Random();
        while (true) {
            double money = random.nextDouble()*5;//得到一个0~5的随机浮点数
            if(money>need){
                money = need;
            }
            try {
                Thread.sleep((int)(money)*1000);
                bank.request(money, number);
                System.out.print(teamName+"成功借了"+money+"个亿!");
                need-=money;
                System.out.println("还需"+need+"亿即可还钱");
                if(need == 0){
                    bank.back(count);
                    System.out.println(teamName+"还了"+count+"亿");
                    break;
                }

            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

运行效果:

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值