银行家算法—java实现
看了网上其他代码(java)的实现,总结以下缺陷
1、资源数目和进程数目是固定的。
2、当一个进程请求资源后导致进入不安全状态时,数据没有回滚到请求之前的状态。
3、当一个进程得到全部需要的资源后,没有把他从进程队列中剔除。
4、每次请求应当建立在上次请求的结果之上。
以上缺陷网上代码可能出现一种或多种,满足不了我追求完美的心,哈哈哈,所以我自己写了一个解决了以上所有缺陷。
欢迎白嫖 给个赞就行。
先看运行结果:
运行结果:
输入资源数目
3
输入进程数目
5
请输入Max矩阵
7 5 3
3 2 2
9 0 2
2 2 2
4 3 3
请输入allocation矩阵
0 1 0
2 0 0
3 0 2
2 1 1
0 0 2
输入当前可用资源
3 3 2
max allocation need avialiable
p0 7 5 3 0 1 0 7 4 3 3 3 2
p1 3 2 2 2 0 0 1 2 2
p2 9 0 2 3 0 2 6 0 0
p3 2 2 2 2 1 1 0 1 1
p4 4 3 3 0 0 2 4 3 1
进程 Work Alloction Need Work+Alloction
P1 3 3 2 | 2 0 0 | 1 2 2 | 5 3 2
P3 5 3 2 | 2 1 1 | 0 1 1 | 7 4 3
P4 7 4 3 | 0 0 2 | 4 3 1 | 7 4 5
P0 7 4 5 | 0 1 0 | 7 4 3 | 7 5 5
P2 7 5 5 | 3 0 2 | 6 0 0 | 10 5 7
此时存在一个安全序列:P1 P3 P4 P0 P2 故当前可分配!
max allocation need avialiable
p0 7 5 3 0 1 0 7 4 3 3 3 2
p1 3 2 2 2 0 0 1 2 2
p2 9 0 2 3 0 2 6 0 0
p3 2 2 2 2 1 1 0 1 1
p4 4 3 3 0 0 2 4 3 1
max allocation need avialiable
p0 7 5 3 0 1 0 7 4 3 3 3 2
p1 3 2 2 2 0 0 1 2 2
p2 9 0 2 3 0 2 6 0 0
p3 2 2 2 2 1 1 0 1 1
p4 4 3 3 0 0 2 4 3 1
请输入请求资源的进程编号:
2
请输入请求各资源的数量:
0 0 2
即进程P2对各资源请求Request:(0,0,2).
进程P2请求已经超出最大需求量Need.
您是否还要进行请求:y/n?
y
请输入请求资源的进程编号:
1
请输入请求各资源的数量:
0 0 2
即进程P1对各资源请求Request:(0,0,2).
max allocation need avialiable
p0 7 5 3 0 1 0 7 4 3 3 3 0
p1 3 2 2 2 0 2 1 2 0
p2 9 0 2 3 0 2 6 0 0
p3 2 2 2 2 1 1 0 1 1
p4 4 3 3 0 0 2 4 3 1
现在进入安全算法:
进程 Work Alloction Need Work+Alloction
P1 3 3 0 | 2 0 2 | 1 2 0 | 5 3 2
P3 5 3 2 | 2 1 1 | 0 1 1 | 7 4 3
P4 7 4 3 | 0 0 2 | 4 3 1 | 7 4 5
P0 7 4 5 | 0 1 0 | 7 4 3 | 7 5 5
P2 7 5 5 | 3 0 2 | 6 0 0 | 10 5 7
此时存在一个安全序列:P1 P3 P4 P0 P2 故当前可分配!
max allocation need avialiable
p0 7 5 3 0 1 0 7 4 3 3 3 0
p1 3 2 2 2 0 2 1 2 0
p2 9 0 2 3 0 2 6 0 0
p3 2 2 2 2 1 1 0 1 1
p4 4 3 3 0 0 2 4 3 1
您是否还要进行请求:y/n?
y
请输入请求资源的进程编号:
4
请输入请求各资源的数量:
3 0 0
即进程P4对各资源请求Request:(3,0,0).
max allocation need avialiable
p0 7 5 3 0 1 0 7 4 3 0 3 0
p1 3 2 2 2 0 2 1 2 0
p2 9 0 2 3 0 2 6 0 0
p3 2 2 2 2 1 1 0 1 1
p4 4 3 3 3 0 2 1 3 1
现在进入安全算法:
进程 Work Alloction Need Work+Alloction
当前系统处于不安全状态,故不存在安全序列 。
--------恢复数据------
max allocation need avialiable
p0 7 5 3 0 1 0 7 4 3 3 3 0
p1 3 2 2 2 0 2 1 2 0
p2 9 0 2 3 0 2 6 0 0
p3 2 2 2 2 1 1 0 1 1
p4 4 3 3 0 0 2 4 3 1
您是否还要进行请求:y/n?
y
请输入请求资源的进程编号:
0
请输入请求各资源的数量:
0 2 0
即进程P0对各资源请求Request:(0,2,0).
max allocation need avialiable
p0 7 5 3 0 3 0 7 2 3 3 1 0
p1 3 2 2 2 0 2 1 2 0
p2 9 0 2 3 0 2 6 0 0
p3 2 2 2 2 1 1 0 1 1
p4 4 3 3 0 0 2 4 3 1
现在进入安全算法:
进程 Work Alloction Need Work+Alloction
当前系统处于不安全状态,故不存在安全序列 。
--------恢复数据------
max allocation need avialiable
p0 7 5 3 0 1 0 7 4 3 3 3 0
p1 3 2 2 2 0 2 1 2 0
p2 9 0 2 3 0 2 6 0 0
p3 2 2 2 2 1 1 0 1 1
p4 4 3 3 0 0 2 4 3 1
您是否还要进行请求:y/n?
2.代码
代码如下:
package Yinhangjia;
import java.util.Scanner;
/**银行家算法
* @author hrl
* @date 2021年04月24日12:57
*/
class Banker {
int max[][] = new int[100][100];
int allocation[][] = new int[100][100];
int need[][] = new int[100][100];
int avialiable[] = new int[100];
int request[][] = new int[100][100];
boolean[] finish = new boolean[100];//进程是否结束
int work[] = new int[100];
//资源数目
int scount ;
//进程数目;
int pcount;
//剩余进程的个数
int fcount;
int num = 0;//进程编号
Scanner in = new Scanner(System.in);
//数据备份
int b_allocation[][] = new int[100][100];
int b_max[][] = new int[100][100];
int b_avialiable[] = new int[100];
int b_need[][] = new int[100][100];
boolean[] b_finish = new boolean[100];
/*
* 初始化
* @author hrl
* @date 2021/4/24 14:08
*/
public void intit(){
Scanner scanner = new Scanner(System.in);
System.out.println("输入资源数目");
scount =scanner.nextInt();
System.out.println("输入进程数目");
pcount = scanner.nextInt();
fcount =pcount;
System.out.println("请输入Max矩阵");
for(int i = 0 ; i<pcount; i++) {
for(int j= 0 ;j < scount; j++) {
max[i][j]= scanner.nextInt();
}
}
System.out.println("请输入allocation矩阵");
for(int i = 0 ; i<pcount; i++) {
for(int j= 0 ;j < scount; j++) {
allocation[i][j]= scanner.nextInt();
}
}
//计算need[][]
for(int i = 0 ; i<pcount; i++) {
for(int j= 0 ;j < scount; j++) {
need[i][j] = max[i][j] - allocation[i][j];
}
}
System.out.println("输入当前可用资源");
for(int i = 0 ; i < scount ; i ++) {
avialiable[i] = scanner.nextInt();
}
//初始化finish
for(int i =0 ; i < pcount; i++) {
finish[i] = false;
}
dispaly();
SecurityAlgorithm();
}
/*
* 显示资源状况
* @author hrl
* @date 2021/4/24 14:25
* @param null
* @return null
*/
public void dispaly () {
System.out.println(" max allocation need avialiable");
boolean flag = true;
for (int i =0; i < pcount; i++ ) {
if(!finish[i]) {
System.out.print("p"+i+" " );
for (int j = 0; j < scount; j++){
System.out.print(max[i][j]+" ");
}
System.out.print(" ");
for (int j = 0; j < scount; j++){
System.out.print(allocation[i][j]+" ");
}
System.out.print(" ");
for (int j = 0; j < scount; j++){
System.out.print(need[i][j]+" ");
}
System.out.print(" ");
if(flag ){
for (int j = 0; j < scount; j++){
System.out.print(avialiable[j]+" ");
}
flag=false;
}
System.out.println('\n');
}
}
}
//判断 请求资源是否超过 需要的资源
public boolean eq2Arry(int request[][],int need[][],int num){
boolean result = true;
for(int i = 0 ; i < scount;i++) {
if(request[num][i] > need[num][i]){
result =false;
break;
}
}
return result;
}
//判断可用资源是否大于 请求资源
public boolean eq1Arry(int request[][],int avialiable[],int num) {
boolean result = true;
for(int i = 0 ; i < scount; i++) {
if(request[num][i] > avialiable[i]){
result= false;
break;
}
}
return result;
}
public void setRequest() {//设置请求资源量Request
System.out.println("请输入请求资源的进程编号:");
num= in.nextInt();//设置全局变量进程编号num
System.out.println("请输入请求各资源的数量:");
for (int j = 0; j < scount; j++) {
request[num][j] = in.nextInt();
}
System.out.println("即进程P" + num + "对各资源请求Request:(" + request[num][0] + "," + request[num][1] + "," + request[num][2] + ").");
BankerAlgorithm();
}
//备份数据
public void save (int ma[][],int all[][],int ava[],boolean rollback){
//rollback 为真 恢复数据
if(rollback){
for(int i = 0; i < pcount; i++ ){
for(int j = 0 ; j < scount; j++){
allocation[i][j] = b_allocation[i][j];
max[i][j] = b_max[i][j];
need[i][j]= b_need[i][j];
}
avialiable[i] = b_avialiable[i];
finish[i]=b_finish[i];
}
}else {
for(int i = 0; i < pcount; i++ ){
for(int j = 0 ; j < scount; j++){
b_allocation[i][j] = allocation[i][j];
b_max[i][j] = max[i][j] ;
b_need[i][j] = need[i][j] ;
}
b_avialiable[i] = avialiable[i] ;
b_finish[i] = finish[i];
}
}
}
//判断请求是否合法
public void BankerAlgorithm() {//银行家算法
boolean T=true;
if (eq2Arry(request,need,num)) {//判断Request是否小于Need
if (eq1Arry(request,avialiable,num)) {//判断Request是否小于Alloction
//数据备份
save(max,allocation,avialiable,false);
for (int i = 0; i < scount; i++) {
avialiable[i] -= request[num][i];
allocation[num][i] += request[num][i];
need[num][i] -= request[num][i];
}
} else {
System.out.println("当前没有足够的资源可分配,进程P" + num + "需等待。");
T=false;
}
} else {
System.out.println("进程P" + num + "请求已经超出最大需求量Need.");
T=false;
}
if(T==true){
dispaly();
System.out.println("现在进入安全算法:");
SecurityAlgorithm();
}
}
//安全检测
public void SecurityAlgorithm() {//安全算法
Boolean Finish[] = new Boolean[100];
for(int i =0 ; i < pcount; i++) {
Finish[i] = false;
}
int count = 0;//完成进程数
int circle=0;//循环圈数
int[] S=new int[100];//安全序列
for (int i = 0; i < scount; i++) {//设置工作向量
work[i] = avialiable[i];
}
boolean flag = true;
while (count < fcount) {
if(flag){
System.out.println("进程 "+" Work "+" Alloction "+" Need "+" Work+Alloction ");
flag = false;
}
for (int i = 0; i < pcount; i++) {
if (Finish[i]==false && finish[i] == false && eq1Arry(need,work,i) ) {//判断条件
System.out.print("P"+i+" ");
for (int k = 0; k < scount; k++){
System.out.print(work[k]+" ");
}
System.out.print("| ");
for (int j = 0; j<scount;j++){
work[j]+=allocation[i][j];
}
Finish[i]=true;//当当前进程能满足时
S[count]=i;//设置当前序列排号
count++;//满足进程数加1
for(int j=0;j<scount;j++){
System.out.print(allocation[i][j]+" ");
}
System.out.print("| ");
for(int j=0;j<scount;j++){
System.out.print(need[i][j]+" ");
}
System.out.print("| ");
for(int j=0;j<scount;j++){
System.out.print(work[j]+" ");
}
System.out.println();
}
}
circle++;//循环圈数加1
if(count==fcount){//判断是否满足所有进程需要
System.out.print("此时存在一个安全序列:");
for (int i = 0; i<fcount;i++){//输出安全序列
System.out.print("P"+S[i]+" ");
}
//保存
gcS();
save(max,allocation,avialiable,false);
System.out.println("故当前可分配!");
dispaly();
break;//跳出循环
}
if(count<circle){//判断完成进程数是否小于循环圈数
count=pcount;
System.out.println("当前系统处于不安全状态,故不存在安全序列 。 ");
System.out.println("--------恢复数据------ ");
save(max,allocation,avialiable,true);
dispaly();
break;//跳出循环
}
}
}
// public 资源回收
public void gcS(){
for (int i = 0 ; i < pcount ; i++) {
int index ;
boolean flag = true;
for(int j = 0; j < scount; j++) {
if(need[i][j] != 0 ) {
flag = false;
index =j;
}
}
//如果need 对接数据为0 回收数据
if(flag && finish[i] == false){
for(int a =0; a < scount; a++){
avialiable[a]+= max[i][a];
max[i][a] = 0;
}
finish[i] = true;
fcount--;
}
}
//保存
save(max,allocation,avialiable,false);
}
}
主函数代码
package Yinhangjia;
import java.util.Scanner;
/**
* @author hrl
* @date 2021年04月24日13:52
*/
public class Main {
/*
*
* @author hrl
* @date 2021/4/24 14:39
* @param null
* @return null
* 输入资源数目
3
进程数目
5
max
7 5 3
3 2 2
9 0 2
2 2 2
4 3 3
need
0 1 0
2 0 0
3 0 2
2 1 1
0 0 2
avaliable
3 3 2
*/
public static void main(String[] args) {
boolean Choose = true;
String flag;
Scanner in = new Scanner(System.in);
Banker banker = new Banker();
banker.intit();//初始化
banker.dispaly();//显示
while (Choose == true) {
banker.setRequest();
System.out.println("您是否还要进行请求:y/n?");
flag = in.nextLine();
if (flag.endsWith("n")) {
Choose = false;
}
}
}
}
测试数据也在上面了 。 欢迎白嫖 给个赞就行