操作系统-银行家算法(安全性算法)进程死锁检测
import java.util.Scanner;
public class bank {
private final int M = 3; //资源数量
private final int N = 5; //进程数量
private final int num = 97; //支持小写字母的进程号,如果是大写字母例如:ABCD进程,则将num改成65,数字的话就改为48
public void output(int[][] iMax, int[][] iAllocation, int[][] iNeed, int[] iAvailable, char[] cName) {
int i, j;
System.out.println("\n\t Max \tAllocation\t Need \t Available");
System.out.println("\tA B C\tA B C\tA B C\t A B C");
for (i = 0; i < N; i++) {
System.out.print(cName[i] + "\t");
for (j = 0; j < M; j++)
System.out.print(iMax[i][j] + " ");
// System.out.print("\t");
for (j = 0; j < M; j++)
System.out.print(iAllocation[i][j] + " ");
// System.out.print("\t");
for (j = 0; j < M; j++)
System.out.print(iNeed[i][j] + " ");
// System.out.print("\t");
System.out.print(" ");
//Available只需要输出一次
if (i == 0)
for (j = 0; j < M; j++)
System.out.print(iAvailable[j] + " ");
System.out.println("");
}
}
public boolean safety(int[][] iAllocation, int[][] iNeed, int[] iAvailable, char[] cName) {
int work[] = new int[M];
for (int i = 0; i < M; i++) {
work[i] = iAvailable[i];
}
boolean Finish[] = new boolean[N];
for (boolean x : Finish) { //初始化Finish
x = false;
}
int count = N;
while (count <= N) {
for (int i = 0; i < N; i++) {
if (!Finish[i]) {
for (int j = 0; j < M; j++) {
if (iNeed[i][j] <= work[j]) {
Finish[i] = true;
} else {
Finish[i] = false;
break;
}
}
if (Finish[i]) {
for (int k = 0; k < M; k++)
work[k] = work[k] + iAllocation[i][k];
i = -1;
}
}
}
for (int k = 0; k < N; k++) {
if (!Finish[k]) {
return false;
}
}
System.out.println("");
count++;
}
//
return true;
}
public boolean banker(int[][] iAllocation, int[][] iNeed, int[] iAvailable, char[] cName) {
Scanner in = new Scanner(System.in);
int[] request = new int[N];
System.out.println("可用的资源数量如下");
for (int i = 0; i < M; i++) {
System.out.print(i + ":" + iAvailable[i] + " ");
}
char process_char = '0'; //进程号
System.out.println("请输入进程号,可用的进程号如下");
for (int j = 0; j < N; j++) {
System.out.print(cName[j] + " ");
}
System.out.println("");
//------------------------------------------------判断输入的正确性
boolean flag = true;
while (flag) //判断输入是否正确
{
int j = 0;
process_char = (in.next().toCharArray())[0];
for (j = 0; j < N; j++) {
if (process_char == cName[j]) {
flag = false;
break;
}
}
if ((j >= N - 1) && flag)
System.out.println("输入有误请重新输入");
}
int process = process_char -num; //将字母的进程号转为数字
System.out.println("所选进程为" + process);
System.out.println("请输入请求的资源数");
//---------------------------------------------------判断输入的正确性
for (int i = 0; i < M; i++) {
boolean inputFlag=true;
String c = in.next();
for (int m = 0; m < c.length(); m++) {
if (!Character.isDigit(c.charAt(m))) {
System.out.println("输入有误请重新输入");
i = -1;
inputFlag=false;
break;
}
}
if(inputFlag)
{
request[i]=Integer.parseInt(c);
}
}
//----------------------------------------------------------------银行家算法检测
for (int i = 0; i < M; i++) {
if (request[i] > iNeed[process][i]) //如果需求量小于最大需求数则退回
{
System.out.println("请求量超过该进程的资源最大需求量");
return false;
}
if (request[i] > iAvailable[i]) //如果请求量大于系统目前的资源数,则退回
{
System.out.println("请求量超过系统的目前的可用资源总数");
return false;
}
}
for (int i = 0; i < M; i++) //试分配
{
iAvailable[i] = iAvailable[i] - request[i];
iAllocation[process][i] = iAllocation[process][i] + request[i];
iNeed[process][i] = iNeed[process][i] - request[i];
}
boolean flag2 = true;
flag2 = safety(iAllocation, iNeed, iAvailable, cName);
if (!flag2) //如果安全行算法检验成功
{
System.out.println("可能造成死锁");
for (int i = 0; i < M; i++) //还原
{
iAvailable[i] = iAvailable[i] + request[i];
iAllocation[process][i] = iAllocation[process][i] - request[i];
iNeed[process][i] = iNeed[process][i] + request[i];
}
return false;
}
System.out.println("请求成功");
return true;
}
public void bank_execute() {
int i, j;
//当前可用每类资源的资源数
int[] iAvailable = {3, 3, 2};
//系统中N个进程中的每一个进程对M类资源的最大需求
int[][] iMax = {{7, 5, 3}, {3, 2, 2}, {9, 0, 2}, {2, 2, 2}, {4, 3, 3}};
//iNeed[N][M]每一个进程尚需的各类资源数
//iAllocation[N][M]为系统中每一类资源当前已分配给每一进程的资源数
int[][] iNeed = new int[N][M];
int[][] iAllocation = {{0, 1, 1}, {2, 0, 0}, {3, 0, 2}, {2, 1, 1}, {0, 0, 2}};
//进程名
char[] cName = {'a', 'b', 'c', 'd', 'e'};
boolean bExitFlag = true; //退出标记
String ch; //接收选择是否继续提出申请时传进来的值
boolean bSafe; //存放安全与否的标志
//计算iNeed[N][M]的值
for (i = 0; i < N; i++)
for (j = 0; j < M; j++)
iNeed[i][j] = iMax[i][j] - iAllocation[i][j];
output(iMax, iAllocation, iNeed, iAvailable, cName);
bSafe = banker(iAllocation, iNeed, iAvailable, cName);
//是否继续
while (bExitFlag) {
System.out.println("继续提出申请?y为是;n为否");
Scanner in = new Scanner(System.in);
ch = in.next();
switch (ch) {
case "y":
bSafe = banker(iAllocation, iNeed, iAvailable, cName);
if (bSafe) //安全,则输出变化后的数据
output(iMax, iAllocation, iNeed, iAvailable, cName);
break;
case "no":
System.out.println("退出");
;
bExitFlag = false;
break;
default:
System.out.println("输入有误,请重新输入:");
}
}
}
public static void main(String[] args) {
new bank().bank_execute();
}
}
public void output(int[][] iMax, int[][] iAllocation, int[][] iNeed, int[] iAvailable, char[] cName) 方法是将进程,资源信息输出。
注意开头注释中的内容(即进程号是用什么表示的,字母还是数字)。