0
点赞
收藏
分享

微信扫一扫

避免“死锁”之银行家算法的模拟实现


BankerAlgorithm.java

/**    
* @Title: BankerAlgorithm.java
* @Package banker
* @Description: 银行家算法
* @author weigion
* @date 2018-06-20 08:50:05
* @version V1.0
*/
package banker;

import java.util.Scanner;

/**
* @ClassName: BankerAlgorithm
* @Description: 银行家算法核心代码
* @author weigion
* @date 2018-06-20 08:50:05
*/
public class BankerAlgorithm {

/** 银行家算法需要设置四个数据结构,即
* (1)所有进程对资源的最大需求Max,
* (2)系统中的资源分配Allocation,
* (3)所有进程还需要的资源情况Need,
* (4)描述系统中可利用的资源Available,
*/

int m; // 定义进程数
int n; // 每个进程的资源数
int[][] max; // 最大需求矩阵,定义系统中m个进程对n类资源的最大需求
int[][] allocation; // 分配矩阵,定义已分配的资源数
int[][] need; // 需求矩阵,定义需求的资源
int[] available; // 可利用资源向量
Scanner sc = new Scanner(System.in);

public BankerAlgorithm() {
System.out.println("请输入进程数m:");
m = sc.nextInt();
System.out.println("请输入进程资源数n:");
n = sc.nextInt();
max = new int[m][n];
allocation = new int[m][n];
need = new int[m][n];
available = new int[n];

System.out.println("请输入一个" + m + "行" + n + "列的各进程的最大需求量");
for (int i = 0; i < max.length; i++) { // 依次输入系统中m个进程对n类资源的最大需求
System.out.println("请输入p(" + i + ")进程的Max:");
for (int j = 0; j < max[i].length; j++) {
max[i][j] = sc.nextInt();
}
}
System.out.println("请输入一个" + m + "行" + n + "列的各进程的各占有量:");
for (int i = 0; i < allocation.length; i++) { // 依次输入进程的各个占有资源数
System.out.println("请输入p(" + i + ")进程中的Allocation:");
for (int j = 0; j < allocation[i].length; j++) {
allocation[i][j] = sc.nextInt();
}
}
for (int i = 0; i < need.length; i++) { // 计算出各个进程需求的资源数
for (int j = 0; j < need[i].length; j++) {
need[i][j] = max[i][j] - allocation[i][j];
}
}
System.out.println("请输入可用资源数Available:"); // 输入进程的可用资源数
for (int i = 0; i < n; i++) {
available[i] = sc.nextInt();
}
System.out.println("初始化结果为下表:");
print();
}

// 显示列表
public void print() {
System.out.println("------------------------------------------");
System.out.println("\tMax\tAllocation\tNeed\tAvailable");
System.out.println("\tA B C\tA B C\t\tA B C\tA B C");
for (int i = 0; i < m; i++) {
System.out.print("P(" + i + "): "+" ");
for (int j = 0; j < n; j++) {
System.out.print(max[i][j] + " ");
}
System.out.print("\t");
for (int j = 0; j < n; j++) {
System.out.print(allocation[i][j] + " ");
}
System.out.print("\t\t");
for (int j = 0; j < n; j++) {
System.out.print(need[i][j] + " ");
}
System.out.print("\t");
if (i == 0) {
for (int j = 0; j < n; j++) {
System.out.print(available[j] + " ");
}
}
System.out.println();
}
System.out.println("------------------------------------------");
}

/**
* 安全性算法检查
* 设置两个向量:work和finish
*/
public boolean checkSecurity() {
int[] work = new int[n]; // 工作向量,表示系统可提供给进程继续运行的各类资源数目
boolean[] finish = new boolean[m]; // 标志一个进程是否完成?true 表示完成 false 表示未完成

int numberResource = 0; // 资源数
int numberProcess = 0; // 进程数
int countAllocation = 0; // 记录可以分配的序列
int countProcess = 0; // 记录所有序列分配的进程总数
int[] p = new int[m]; // 记录进程的安全序列


for (int i = 0; i < n; i++) {
work[i] = available[i];
}

//开始把进程未分配状态设置为false
for (int i = 0; i < m; i++) {
finish[i] = false;
}

while (numberProcess < m) {
for (int i = 0; i < m; i++) {
if (finish[i] == false) {// 判断finish的状态,如果为true说明刚才已经找到,不需要重复。
for (int j = 0; j < n; j++) {
if (need[i][j] <= work[j]) {// 比较一个进程的各种资源是否满足条件
numberResource++;//满足的数量
}
}
if (numberResource == n) {// 如果一个进程所有资源都满足条件need<=work,则说明找到了一个进程满足
for (int j = 0; j < n; j++) {
work[j] = work[j] + allocation[i][j];
}
finish[i] = true;// 找到一个进程满足
p[countAllocation++] = i;// 记录找到的是第几个进程
}
}
numberResource = 0;// 必须把它清零,重新来找资源数是否都满足条件
}
numberProcess++;
}

// 记录有多少个序列;
for (int i = 0; i < m; i++) {
if (finish[i] == true) {
countProcess++;// 检测是否所有的进程最后都是true,
}
}
if (countProcess == m) {// 相等表明找到了安全的序列
System.out.println("存在一个安全序列,安全序列为:");
for (int i = 0; i < m; i++) {
if (i != m - 1) {
System.out.print("P" + p[i] + "-->");
} else {
System.out.println("P" + p[i]);
}
}
System.out.println("----------------------------------------------------");
return true;
} else {
System.out.println("没有找到安全序列,系统处于不安全状态!");
return false;
}
}

//银行家算法:请求资源
public void checkRequest() {
int process = 0; // 记录输入的是第几个进程
int countAllocation = 0; // 记录试分配过程中满足条件的个数
boolean flag = true; // 主要防止输入的数字已经超出了本来process数量,则要求重新输入
System.out.println("请输入要申请进程:p0~p"+(m-1)+"输入数字" );
while (flag) {
process = sc.nextInt();
if (process >= m) {
System.out.println("输入超出了进程数,请重新输入!");
} else {
flag = false;

}
}
System.out.println("p"+process+"进程发出请求");
int[] request = new int[n];
System.out.println("输入要请求的资源Request:");
for (int i=0;i<n;i++) {
request[i] = sc.nextInt();
}
// 判断是否可以分配
for (int i=0;i<n;i++) {
if (request[i] <= need[process][i] && request[i] <= available[i]) {
countAllocation++;// 判断是否每个进程的所有资源都满足试分配的要求,并记录。
}
}

if (countAllocation == n) {// 如果每一种资源都满足要求,则可以进程请求试分配
for (int j=0;j<n;j++) {
allocation[process][j] += request[j]; //注意数组下标是从0开始的
need[process][j] -= request[j];
available[j] -= request[j];
}

System.out.println("试分配如下-------->");
print();// 打印试分配的结果
System.out.println("进行安全性判断");
flag = checkSecurity();// 判断是否为安全序列
if (flag==false) { //如果是分配后不能找到一个安全序列,则返回,不进行分配
for (int j=0;j<n;j++) {
allocation[process][j] -= request[j]; //注意数组下标是从0开始的
need[process][j] += request[j];
available[j] += request[j];
}
}
} else {
System.out.println("不能进行试分配,找不到安全序列");
}
}

}

Main.java

/**    
* @Title: Main.java
* @Package banker
* @Description: 死锁避免之银行家算法模拟实现
* @author weigion
* @date 2018-06-20 08:46:38
* @version V1.0
*/
package banker;

import java.util.Scanner;

/**
* @ClassName: Main
* @Description: 死锁避免之银行家算法模拟实现的测试部分
* @author weigion
* @date 2018-06-20 08:46:38
*/
public class Main {

public static void main(String[] args) {
System.out.println("*****死锁避免之银行家算法模拟实现*****");
BankerAlgorithm bankerAlgorithm = new BankerAlgorithm();
boolean flag = true;
while (flag) {
System.out.println("*****死锁避免之银行家算法模拟实现*****");
System.out.println("1.安全序列检测");
System.out.println("2.试分配");
System.out.println("3.退出!");
System.out.println("----------------------------------------------------------");
System.out.println("请选择");
Scanner sc = new Scanner(System.in);
int count = sc.nextInt();
switch (count) {
case 1:
bankerAlgorithm.checkSecurity();
break;
case 2:
bankerAlgorithm.checkRequest();// 请求资源检测
break;
case 3:
System.out.println("谢谢使用!!!");
flag = false;
sc.close();
break;
}
}
}

}

结果:

避免“死锁”之银行家算法的模拟实现_死锁


举报

相关推荐

0 条评论