JAVA-银行家算法

简介: JAVA-银行家算法

银行家算法是一个避免死锁的著名算法,是由艾兹格.迪杰斯特拉设计的一种避免死锁产生的算法。它以银行借贷系统的分配策略为基础,判断并保证系统的安全运行。

一、背景介绍

在银行中,客户申请贷款的数量是有限的,每个客户在第一次申请贷款时要声明完成该项目所需的最大资金量,在满足所有贷款要求时,客户应及时归还。银行家在客户申请的贷款数量不超过自己拥有的最大值时,都应尽量满足客户的需要。在这样的描述中,银行家就好比操作系统,资金就是资源,客户就相当于要申请资源的进程。

安全序列:指一个进程序列{p1,......,pn}是安全的,即对于每一个进程pi(1<= i<=n),它以后尚需要的资源量不超过系统当前剩余资源量与所有进程pj(j<i)当前占有资源量之和。


安全状态一定是没有死锁发生的。


不安全状态:不存在一个安全序列,不安全状态一定导致死锁。

二、相关数据结构

银行家算法中的数据结构
  • 设系统中有m种不同资源, n个进程
  • Available向量: 系统中尚未分配的每种资源的总量
  • Available[j]: 尚未分配的资源j的数量
  • Max矩阵: 各个进程对每种资源的最大需求量(进程事先声明)
  • Max[i, j](Claim[i,j]): 进程i 对资源j 的最大需求量
  • Allocation矩阵: 当前资源分配状况
  • Allocation[i, j]: 进程i获得的资源j的数量
  • Need矩阵: 每个进程还需要的资源的数量
  • Need[i, j]: 进程i尚需的资源j的数量
各数据结构之间的关系
  • Resource[j] = Available[j] + (Allocation[1, j] + Allocation[2, j] + … + Allocation[n, j])
  • Max[i, j] <= Resource[j]
  • Allocation[i, j] <= Max[i, j]
  • Allocation[i, j] + Need[i, j] =Max[i, j]
安全性算法

1. 设Work和Finish 分别是长度为m 和n 的向量,按如下方式进行初始化:

    Work = Available

           Finish [i] = false ( i =1,2, …, n)

2. 查找这样的i使其满足:(a) Finish [i] = false  (b) Need i <=Work

3. 如果没有这样的 i 存在,那么就转到第4步.

4. Work = Work + Allocation i Finish[i] = True 返回到第2步.

5. 如果对所有的i,Finish [i] == True ,那么系统处于安全状态

例题讲解1

R1,R2,R3的数量分别为(9,3,6); Available(1,1,2)

问:1.该时刻是否为安全状态

      2.进程A请求资源Request(1,0,1),能够分配吗?为什么?

解题步骤如下:(注:!!!圆圈序号表示做题方法,答案中不必出现。)

1.画出如下表格

①首先将available中的数字填在首行work中

②available(1,1,2)分别和A、B、C、D中的need相比较,倘若小于,则从上往下依次选择。例如B(1,0,2)小于则将B填入第一行,其后need、Allocation依次填入


③接着计算work+allocation的值与R1R2R3(9,3,6)相比较,小于则为true


④将上一行中的work+allocation的值填入下一行work中,接着重复②之后的操作。


⑤直到填完最后一个进程,finish都为true则此时产生了一个安全序列。


2.①将requestA和needA和Available相比较,若小于二者则可继续判断,否则不够分配。


RequestA(1,0,1)<=Need(2,2,2)

RequestA(1,0,1)<=Available(1,1,2)


②修改A的allocation和need,allocation+requestA , need-requestA 并将值填入其中。

假定满足进程A的要求,为它分配所申请的资源,并且修改AllocaitonA 和 NeedA,得到:


此时:Available=(0,1,1):不能分配给任何进程;因此不能分配此次请求。


③此时available-requsetA得到(0,1,1)此时,更新A的状态,重复第一问判断是否存在安全状态。通过比较我们发现available(0,1,1)小于任何一个进程的Need故无法进行分配

例题讲解2

设系统在T0时刻系统状态如下:剩余资源向量为: A=(2, 3, 3)


问:① T0时刻是否为安全状态?若是,请给出安全序列。

      ② 在T0时刻若进程P2请求资源(0,3,4),是否能实施资源分配?为什么?

      ③ 在②的基础上,若进程P4请求资源(2,0,1),是否能实施资源分配?为什么?


解析:与题1不同的是,题2并未给出一个系统的表,因此需要在草稿本上列出表格的大概状态。最大资源需求(Max)已分配资源数量(allocation)剩余资源向量(available)


need = max - allocation,其余步骤参考题1 即可


答案:1. 是,安全序列:p4, p5, p1, p2, p3


           2.因为 R(0,3,4)> A (2,3,3,)所以不能分配。


           3.因为R(2,0,1)<=N4(2, 0,1)且 < A(2,3,3)假设可以满足,则N4=(0, 0, 0), A= (0,3,2),在此基础上,是安全的,因此可以实施分配。安全序列为:p4,p5,p1,p2,p3

三、参考示例代码

import java.util.Arrays;
 
class BankersAlgorithm {
    private int[][] max;   // 最大需求矩阵
    private int[][] allocation;   // 已分配资源矩阵
    private int[][] need;   // 剩余需求矩阵
    private int[] available;   // 可用资源向量
    private int[][] request;   // 请求资源矩阵
 
    public BankersAlgorithm(int[][] max, int[][] allocation, int[] available) {
        this.max = max;
        this.allocation = allocation;
        this.available = available;
 
        int numOfProcesses = max.length;
        int numOfResources = available.length;
 
        this.need = new int[numOfProcesses][numOfResources];
        this.request = new int[numOfProcesses][numOfResources];
 
        // 计算剩余需求矩阵
        for (int i = 0; i < numOfProcesses; i++) {
            for (int j = 0; j < numOfResources; j++) {
                need[i][j] = max[i][j] - allocation[i][j];
            }
        }
    }
 
    public void requestResources(int pid, int[] request) {
        System.out.println("进程 " + pid + " 请求资源: " + Arrays.toString(request));
        boolean safe = checkSafety(pid, request);
 
        if (safe) {
            System.out.println("请求通过,为进程 " + pid + " 分配资源 " + Arrays.toString(request));
            allocateResources(pid, request);
        } else {
            System.out.println("请求被拒绝,进程 " + pid + " 等待...");
        }
    }
 
    private boolean checkSafety(int pid, int[] request) {
        int numOfProcesses = max.length;
        int numOfResources = available.length;
 
        int[] work = Arrays.copyOf(available, numOfResources);
        boolean[] finish = new boolean[numOfProcesses];
 
        // 设置该进程的请求资源情况
        for (int i = 0; i < numOfResources; i++) {
            allocation[pid][i] += request[i];
            need[pid][i] -= request[i];
            work[i] -= request[i];
        }
 
        int count = 0;   // 用于统计已分配资源的进程数
        boolean hasFinished = true;   // 标识是否存在符合条件的进程
 
        while (count < numOfProcesses && hasFinished) {
            hasFinished = false;
 
            for (int i = 0; i < numOfProcesses; i++) {
                if (!finish[i] && checkNeedLessOrEqual(work, need[i])) {
                    // 分配资源给进程
                    for (int j = 0; j < numOfResources; j++) {
                        work[j] += allocation[i][j];
                    }
                    finish[i] = true;
                    count++;
                    hasFinished = true;
                }
            }
        }
 
        // 恢复该进程的请求资源情况
        for (int i = 0; i < numOfResources; i++) {
            allocation[pid][i] -= request[i];
            need[pid][i] += request[i];
            work[i] += request[i];
        }
 
        return count == numOfProcesses;
    }
 
    private boolean checkNeedLessOrEqual(int[] work, int[] need) {
        for (int i = 0; i < work.length; i++) {
            if (work[i] < need[i]) {
                return false;
            }
        }
        return true;
    }
 
    private void allocateResources(int pid, int[] request) {
        int numOfResources = available.length;
 
        for (int i = 0; i < numOfResources; i++) {
            available[i] -= request[i];
            allocation[pid][i] += request[i];
            need[pid][i] -= request[i];
        }
    }
}
 
public class TestBanker {
    public static void main(String[] args) {
        int[][] max = {
                {7, 5, 3},
                {3, 2, 2},
                {9, 0, 2},
                {2, 2, 2},
                {4, 3, 3}
        };
 
        int[][] allocation = {
                {0, 1, 0},
                {2, 0, 0},
                {3, 0, 2},
                {2, 1, 1},
                {0, 0, 2}
        };
 
        int[] available = {3, 3, 2};
 
        // 继续编写您想要的代码逻辑
    }
}
相关文章
|
3月前
|
存储 监控 算法
企业上网监控场景下布隆过滤器的 Java 算法构建及其性能优化研究
布隆过滤器是一种高效的数据结构,广泛应用于企业上网监控系统中,用于快速判断员工访问的网址是否为违规站点。相比传统哈希表,它具有更低的内存占用和更快的查询速度,支持实时拦截、动态更新和资源压缩,有效提升系统性能并降低成本。
104 0
|
3月前
|
存储 负载均衡 算法
我们来说一说 Java 的一致性 Hash 算法
我是小假 期待与你的下一次相遇 ~
126 1
|
4月前
|
Java
银行转账p图软件,对公转账截图生成器,java版开发银行模拟器【仅供学习参考】
这是一套简单的银行账户管理系统代码,包含`BankAccount`和`BankSystem`两个核心类。`BankAccount`负责单个账户的管理
|
4月前
|
存储 Java 数据库
银行流水生成器在线制作,银行转账p图在线生成,java实现最牛的生成器【仅供学习用途】
本示例展示了一个基于Java的银行交易记录管理系统基础架构,涵盖交易记录生成、数字签名加密及账本存储功能。核心内容包括:1) TransactionRecord类
|
4月前
|
Java 数据库 数据安全/隐私保护
银行流水生成器在线制作,银行转账p图在线生成,java实现最牛的生成器【仅供学习用途】
本资料探讨银行系统核心技术,涵盖交易记录生成、电子回单加密验真及基于Java的财务管理系统开发。主要内容包括:交易记录实体类设计(不可变性与数字签名)
|
4月前
|
存储 算法 安全
Java中的对称加密算法的原理与实现
本文详细解析了Java中三种常用对称加密算法(AES、DES、3DES)的实现原理及应用。对称加密使用相同密钥进行加解密,适合数据安全传输与存储。AES作为现代标准,支持128/192/256位密钥,安全性高;DES采用56位密钥,现已不够安全;3DES通过三重加密增强安全性,但性能较低。文章提供了各算法的具体Java代码示例,便于快速上手实现加密解密操作,帮助用户根据需求选择合适的加密方案保护数据安全。
369 58
|
5月前
|
人工智能 算法 NoSQL
LRU算法的Java实现
LRU(Least Recently Used)算法用于淘汰最近最少使用的数据,常应用于内存管理策略中。在Redis中,通过`maxmemory-policy`配置实现不同淘汰策略,如`allkeys-lru`和`volatile-lru`等,采用采样方式近似LRU以优化性能。Java中可通过`LinkedHashMap`轻松实现LRUCache,利用其`accessOrder`特性和`removeEldestEntry`方法完成缓存淘汰逻辑,代码简洁高效。
227 0
|
5月前
|
存储 缓存 监控
上网行为监控系统剖析:基于 Java LinkedHashMap 算法的时间序列追踪机制探究
数字化办公蓬勃发展的背景下,上网行为监控系统已成为企业维护信息安全、提升工作效能的关键手段。该系统需实时记录并深入分析员工的网络访问行为,如何高效存储和管理这些处于动态变化中的数据,便成为亟待解决的核心问题。Java 语言中的LinkedHashMap数据结构,凭借其独有的有序性特征以及可灵活配置的淘汰策略,为上网行为监控系统提供了一种兼顾性能与功能需求的数据管理方案。本文将对LinkedHashMap在上网行为监控系统中的应用原理、实现路径及其应用价值展开深入探究。
119 3
|
5月前
|
负载均衡 算法 关系型数据库
大数据大厂之MySQL数据库课程设计:揭秘MySQL集群架构负载均衡核心算法:从理论到Java代码实战,让你的数据库性能飙升!
本文聚焦 MySQL 集群架构中的负载均衡算法,阐述其重要性。详细介绍轮询、加权轮询、最少连接、加权最少连接、随机、源地址哈希等常用算法,分析各自优缺点及适用场景。并提供 Java 语言代码实现示例,助力直观理解。文章结构清晰,语言通俗易懂,对理解和应用负载均衡算法具有实用价值和参考价值。
大数据大厂之MySQL数据库课程设计:揭秘MySQL集群架构负载均衡核心算法:从理论到Java代码实战,让你的数据库性能飙升!
|
6月前
|
存储 机器学习/深度学习 监控
如何监控员工的电脑——基于滑动时间窗口的Java事件聚合算法实现探析​
在企业管理场景中,如何监控员工的电脑操作行为是一个涉及效率与合规性的重要课题。传统方法依赖日志采集或屏幕截图,但数据量庞大且实时性不足。本文提出一种基于滑动时间窗口的事件聚合算法,通过Java语言实现高效、低资源占用的监控逻辑,为如何监控员工的电脑提供一种轻量化解决方案。
148 3

热门文章

最新文章