银行家算法(Java实现)
作者:互联网
前言
银行家算法是最著名的避免死锁的算法。下面用Java来实现它。
代码
主要使用到的类是BankerAlgorithm
。
并且进程的信息是从文件中读入的。
1、使用到的变量
private static final int W = 10, R = 10;
int M, N; //总进程数、资源种类
int[] ALL_RESOURCE = new int[W]; //默认各种资源总数目为10种
int[][] MAX = new int[W][R]; //M个进程对N类资源最大资源需求量
int[] AVAILABLE = new int[R]; // 系统可用资源数
int[][] ALLOCATION = new int[W][R]; // M个进程已经得到N类资源的资源量
int[][] NEED = new int[W][R]; // M个进程还需要N类资源的资源量
int[] Request = new int[R]; // 请求资源个数
int[] P = new int[W]; //进程安全序列
String fileName = "D:\\data.txt";
2、构造器
public BankerAlgorithm() throws FileNotFoundException {
System.out.println("\t\t 银 行 家 算 法");
System.out.println("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
Scanner sc = new Scanner(new FileReader(fileName));
System.out.print("请输入总进程数:");
M = sc.nextInt();
System.out.println(M);
System.out.println("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
System.out.print("请输入总资源种类:");
N = sc.nextInt();
System.out.println(N);
System.out.println("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
System.out.println("请输入各类资源总数:(需要输入数为" + N + "个)");
for (int i = 0; i < N; i++) {
ALL_RESOURCE[i] = sc.nextInt();
System.out.print(ALL_RESOURCE[i] + " ");
}
System.out.println("\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
System.out.println("输入各进程所需最大的各类资源的数量:(需要输入数为" + M
* N + "个)");
for (int i = 0; i < M; i++) {
for (int j = 0; j < N; j++) {
do {
MAX[i][j] = sc.nextInt();
if (MAX[i][j] > ALL_RESOURCE[j])
System.out.println("\n占有资源超过了声明的该资源总数,请重新输入");
} while (MAX[i][j] > ALL_RESOURCE[j]);
System.out.print(MAX[i][j] + " ");
}
System.out.println();
}
System.out.println("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
System.out.println("输入各进程已经占据的各类资源的数量:(需要输入数为" + M
* N + "个)");
for (int i = 0; i < M; i++) {
for (int j = 0; j < N; j++) {
do {
ALLOCATION[i][j] = sc.nextInt();
if (ALLOCATION[i][j] > MAX[i][j])
System.out.println("\n占有资源超过了声明的最大资源,请重新输入");
} while (ALLOCATION[i][j] > MAX[i][j]);
System.out.print(ALLOCATION[i][j] + " ");
}
System.out.println();
}
//初始化资源数量
int p;
for (int j = 0; j < N; j++) {
p = ALL_RESOURCE[j];
for (int i = 0; i < M; i++) {
p = p - ALLOCATION[i][j];// 减去已经被占据的资源
AVAILABLE[j] = p;
if (AVAILABLE[j] < 0)
AVAILABLE[j] = 0;
}
}
for (int i = 0; i < M; i++)
for (int j = 0; j < N; j++)
NEED[i][j] = MAX[i][j] - ALLOCATION[i][j];
output();
bank();
}
3、输出
public void output() {
int i, j;
System.out.println("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
System.out.println("各种资源的总数量:");
for (j = 0; j < N; j++)
System.out.print(" 资源" + j + ": " + ALL_RESOURCE[j]);
System.out.println("\n" + "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
System.out.println("目前各种资源可利用的数量为:");
for (j = 0; j < N; j++)
System.out.print(" 资源" + j + ": " + AVAILABLE[j]);
System.out.println("\n" + "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
System.out.println("各进程还需要的资源数量:");
System.out.print(" ");
for (i = 0; i < N; i++)
System.out.print("资源" + i + " \t");
System.out.println();
for (i = 0; i < M; i++) {
System.out.print("进程" + i + ":\t");
for (j = 0; j < N; j++)
System.out.print(NEED[i][j] + "\t\t");
System.out.println();
}
System.out.println("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
System.out.println("各进程已经得到的资源量: ");
System.out.print(" ");
for (i = 0; i < N; i++)
System.out.print("资源" + i + " \t");
System.out.println();
for (i = 0; i < M; i++) {
System.out.print("进程" + i + ":\t");
for (j = 0; j < N; j++)
System.out.print(ALLOCATION[i][j] + "\t\t");
System.out.println();
}
System.out.println();
}
4、资源分配与回收
//进行资源分配
public void distribute(int k) {
for (int j = 0; j < N; j++) {
AVAILABLE[j] -= Request[j];
ALLOCATION[k][j] += Request[j];
NEED[k][j] -= Request[j];
}
}
//撤销资源分配(与分配相反的操作)
public void restore(int k) {
for (int j = 0; j < N; j++) {
AVAILABLE[j] += Request[j];
ALLOCATION[k][j] -= Request[j];
NEED[k][j] += Request[j];
}
}
5、安全性检查
//安全性检查
public boolean check() {
int[] WORK = new int[R], FINISH = new int[W];
for (int j = 0; j < N; j++) WORK[j] = AVAILABLE[j];
for (int i = 0; i < M; i++) FINISH[i] = 0;
int j;
int l = 0;
for (int i = 0; i < M; i++) {
if (FINISH[i] == 1) continue;
else {
for (j = 0; j < N; j++) {
if (NEED[i][j] > WORK[j]) break;
}
if (j == N) { //说明该行的need需求小于work,可以尝试分配
FINISH[i] = 1; //说明该行(进程)状态为已分配
//回收资源
for (int k = 0; k < N; k++)
WORK[k] += ALLOCATION[i][k];
P[l++] = i; //加入安全队列
i = -1;
} else {
continue;
}
}
if (l == M) { //此时代表安全队列已满,说明当前分配安全
System.out.println("\n 经安全性检查,系统安全,本次分配成功。\n");
System.out.println("安全序列是:");
for (i = 0; i < l; i++) {
System.out.print(P[i]);
if (i != l - 1) System.out.print("-->");
}
System.out.println();
return true;
}
}
System.out.println("\n 系统不安全!!! 本次资源申请不成功!!!\n");
return false;
}
6、银行家算法
public void bank() {
Scanner sc = new Scanner(System.in);
int i, j;
char flag = 'Y';
while (flag == 'Y' || flag == 'y') {
i = -1;
//输入需要申请资源的进程号
while (i < 0 || i >= M) {
System.out.print("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + "\n" + " 请输入需申请资源的进程号:");
i = sc.nextInt();
if (i < 0 || i >= M)
System.out.println(" 输入的进程号不存在,重新输入!");
}
System.out.println("请输入进程" + i + "申请各类资源的数量:");
for (j = 0; j < N; j++) {
System.out.print(" 资源" + j + ": ");
Request[j] = sc.nextInt();
//输入请求大于需求,即不安全
if (Request[j] > NEED[i][j]) {
System.out.println("\n 进程" + i + "申请的资源数大于进程" + i + "还需要" + j + "类资源的数量!" + " 若继续执行系统将处于不安全状态!");
flag = 'N';
break;
} else {
//输入需求大于可用,依旧不安全
if (Request[j] > AVAILABLE[j]) {
System.out.println("\n 进程" + i + "申请的资源数大于进程" + i + "还需要" + j + "类资源的数量!" + " 若继续执行系统将处于不安全状态!");
flag = 'N';
break;
}
}
}
if (flag == 'Y' || flag == 'y') {
distribute(i); // 调用distribute(i),改变资源数
if (!check()) { // 若系统不安全
restore(i); // 调用restore(i)函数,恢复资源数
output(); // 输出资源分配情况
} else // 若系统安全
output(); // 输出资源分配情况
} else
System.out.println();
System.out.print(" 是否继续银行家算法演示,按'Y'或'y'键继续,按'N'或'n'键退出演示: ");
flag = sc.next().charAt(0);
}
}
7、调用
由于把主要算法最终都放在了构造器之中,因而使用时直接new BankerAlgorithm()
即可。
标签:Java,int,print,System,++,算法,println,银行家,out 来源: https://www.cnblogs.com/gogalaxy/p/16205075.html