本文主要是用Java来实现操作系统实验:银行家算法
银行家算法是一种用于避免死锁的资源分配算法,它通过安全性检查来决定是否为进程分配资源,以确保系统不会陷入死锁状态。
在看这段代码之前,我建议读者先去了解银行家算法,再来阅读本文
进程类Process
这里面主要包括进程名,最大需求量,已分配资源数,仍需资源数,未分配的资源
import java.util.ArrayList;
import java.util.List;
class Process {
private String id; // 进程名
private List<Integer> max = new ArrayList<>(); // 最大需求量
private List<Integer> allocation = new ArrayList<>(); // 已分配资源数
private List<Integer> need = new ArrayList<>(); // 仍需资源数
private boolean unassigned; // 未被分配的资源
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public List<Integer> getMax() {
return max;
}
public void addMax(int value) {
max.add(value);
}
public List<Integer> getAllocation() {
return allocation;
}
public void addAllocation(int value) {
allocation.add(value);
}
public List<Integer> getNeed() {
return need;
}
public void setNeed(List<Integer> need) {
this.need = need;
}
public boolean isUnassigned() {
return unassigned;
}
public void setUnassigned(boolean unassigned) {
this.unassigned = unassigned;
}
public List<Integer> calculateNeed() {
List<Integer> calculatedNeed = new ArrayList<>();
for (int i = 0; i < max.size(); i++) {
calculatedNeed.add(max.get(i) - allocation.get(i));
}
return calculatedNeed;
}
}
主函数
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class BankerAlgorithm {
private static final int DEFAULT_NUM = 0; // 默认进程数量
private static final int DEFAULT_CPT = 0; // 默认资源容量
public static void main(String[] args) {
List<Process> processes = new ArrayList<>(); // 进程表
Scanner scanner = new Scanner(System.in);
while (true) {
showMenu();
System.out.print("\n仅输入数字");
System.out.print("\n请输入您选择的操作:");
int select = scanner.nextInt();
switch (select) {
case 0:
System.out.println("您已退出银行家算法,欢迎下次使用!");
return;
case 1:
addProcess(processes, scanner);
break;
case 2:
showProcess(processes);
break;
case 3:
runBankerAlgorithm(processes, scanner);
break;
case 4:
clearProcess(processes);
break;
default:
System.out.println("请输入正确的命令!");
break;
}
}
}
private static void showMenu() {
System.out.println("\t*********************************\t");
System.out.println("\t********* 银行家算法模拟 ********\t");
System.out.println("\t******** 0、退出算法模拟 ********\t");
System.out.println("\t********** 1、添加进程 **********\t");
System.out.println("\t********** 2、展示进程 **********\t");
System.out.println("\t********* 3、银行家算法 *********\t");
System.out.println("\t********** 4、清空进程 **********\t");
System.out.println("\t*********************************\t");
}
private static void addProcess(List<Process> processes, Scanner scanner) {
System.out.print("请输入添加进程的数量:");
int num = scanner.nextInt();
System.out.print("请输入系统资源种类:");
int cpt = scanner.nextInt();
for (int i = 0; i < num; i++) {
Process newProcess = new Process();
System.out.println("添加第" + (i + 1) + "进程");
System.out.print("请输入进程名:");
newProcess.setId(scanner.next());
System.out.print("请输入最大需求量:");
for (int j = 0; j < cpt; j++) {
newProcess.addMax(scanner.nextInt());
}
System.out.print("请输入已分配资源数:");
for (int j = 0; j < cpt; j++) {
newProcess.addAllocation(scanner.nextInt());
}
newProcess.setNeed(newProcess.calculateNeed());
newProcess.setUnassigned(true);
processes.add(newProcess);
System.out.println();
}
System.out.println();
}
private static void showProcess(List<Process> processes) {
if (processes.isEmpty()) {
System.out.println("进程表无数据");
} else {
System.out.println("进程表如下:\n");
System.out.println("Process\tMax\tAllocation\tNeed");
StringBuilder sb = new StringBuilder();
for (Process process : processes) {
sb.append(process.getId()).append("\t");
for (int max : process.getMax()) {
sb.append(max).append(" ");
}
sb.append("\t");
for (int allocation : process.getAllocation()) {
sb.append(allocation).append(" ");
}
sb.append("\t\t");
for (int need : process.getNeed()) {
sb.append(need).append(" ");
}
sb.append("\n");
}
System.out.println(sb.toString());
}
System.out.println();
}
private static void clearProcess(List<Process> processes) {
processes.clear();
if (processes.isEmpty()) {
System.out.println("进程表已被清空");
}
}
private static void runBankerAlgorithm(List<Process> processes, Scanner scanner) {
List<Integer> sum = new ArrayList<>(); // 系统各类资源总数
System.out.print("请输入各类资源总数:");
int cpt = processes.get(0).getMax().size();
for (int i = 0; i < cpt; i++) {
sum.add(scanner.nextInt());
}
List<Integer> temp = new ArrayList<>(sum); // 记录资源总数
List<Integer> available = new ArrayList<>(sum); // 系统可用资源数
for (int i = 0; i < cpt; i++) { // 小于资源种类
for (Process process : processes) { // 小于进程数
int newValue = sum.get(i) - process.getAllocation().get(i);
sum.set(i, newValue);
}
}
for (int i = 0; i < cpt; i++) {
available.set(i, sum.get(i));
}
boolean[] finish = new boolean[processes.size()]; // 完成标志数组
List<Integer> safeSequence = new ArrayList<>(); // 安全序列
while (true) {
boolean flag = false;
// for (int i = 0; i < processes.size(); i++) {
// Process process = processes.get(i);
// if (!finish[i] && isNeedLessOrEqual(process, available)) {
// for (int j = 0; j < cpt; j++) {
// int newValue = available.get(j) + process.getAllocation().get(j);
// available.set(j, newValue);
// }
//
// finish[i] = true;
// safeSequence.add(i + 1);
// flag = true;
// }
// }
//上下两种都可以的
for (int i = 0; i < processes.size(); i++) {
Process process = processes.get(i);
if (!finish[i] && isNeedLessOrEqual(process, available)) {
finish[i] = true;
safeSequence.add(i + 1);
flag = true;
final List<Integer> finalAvailable = available;
available = IntStream.range(0, cpt)
.mapToObj(j -> finalAvailable.get(j) + process.getAllocation().get(j))
.collect(Collectors.toList());
}
}
if (!flag) {
break;
}
}
boolean safe = true;
for (boolean f : finish) {
if (!f) {
safe = false;
break;
}
}
if (safe) {
System.out.println("系统是安全的,安全序列为:" + safeSequence);
} else {
System.out.println("系统是不安全的");
}
}
private static boolean isNeedLessOrEqual(Process process, List<Integer> available) {
List<Integer> need = process.getNeed();
for (int i = 0; i < need.size(); i++) {
if (need.get(i) > available.get(i)) {
return false;
}
}
return true;
}
}
希望本文对你有所帮助,如果你觉得有用的不妨点个小小的赞