银行家算法

银行家算法

首先在输入初始化的请求进程的数据时,先对其进行验证是否安全,不安全则自动退出;在安全的情况下,可以对进程进行request请求。进程在请求过程中首先要对请求的资源与本进程所需的资源进行验证,在请求大于所需的情况下,则会出现错误;只有请求的小于或者等于所需时才能进行下一步的验证;在与所需的进程进行的比较合理之后,继续用请求的资源与目前系统所拥有的资源进行比较,在请求的资源小于等于系统目前所拥有的资源时,说明资源请求合理。
在进行请求完成之后,则对请求之后的进程进行运行处理,此时用到安全性算法,经过安全算法之后,不安全的则会发生死锁;安全则说明不会发生死锁。

import java.util.Scanner;

public class Bank {

	public static void main(String[] args) {
		init();
	}

	public static void init() {// 初始化
		Scanner in = new Scanner(System.in);
		// 输入资源种类
		System.out.println("请输入资源种类数:");
		int n = in.nextInt();
		int Available[] = new int[n];
		for (int i = 0; i < n; i++) {
			System.out.print("请输入第" + (i + 1) + "种资源数:");
			Available[i] = in.nextInt();
			System.out.println();
		}

		System.out.print("请输入进程数:");
		int pNum = in.nextInt();
		// 输入进程名字
		String[] pName = new String[pNum];
		for (int i = 0; i < pNum; i++) {
			System.out.println();
			System.out.print("请输入第" + (i + 1) + "个进程的名字:");
			pName[i] = in.next();
		}
		int Max[][] = new int[pNum][n];
		// 输入MAX矩阵
		for (int i = 0; i < pNum; i++) {
			System.out.println();
			System.out.print("请输入" + pName[i] + "进程对" + n + "种资源最大需求:");
			for (int j = 0; j < n; j++) {
				Max[i][j] = in.nextInt();
			}
		}

		// 输入Allocation矩阵
		int Allocation[][] = new int[pNum][n];
		int Need[][] = new int[pNum][n];
		for (int i = 0; i < pNum; i++) {
			System.out.println();
			System.out.print("请输入" + pName[i] + "进程对" + n + "种资源分配的数量:");
			for (int j = 0; j < n; j++) {
				Allocation[i][j] = in.nextInt();
				Available[j] = Available[j] - Allocation[i][j];
				Need[i][j] = Max[i][j] - Allocation[i][j];
			}
		}

		System.out.println("初始资源分配表如下:");
		System.out.println("\tMAx\tAllocation\tNeed\tAvailable");
		for (int i = 0; i < pNum; i++) {
			System.out.print(pName[i]);

			System.out.print("\t");
			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] + " ");
			}

			if (i == 0) {
				System.out.print("\t");
				for (int j = 0; j < n; j++) {
					System.out.print(Available[j] + " ");
				}
			}

			System.out.println();
		}
		boolean s = security(pNum, Available, Allocation, Need, pName);
		if (s) {
			System.out.println("安全");
			System.out.println("是否有请求进程?(输入y确认)");
			String y = in.next();

			while (y.equals("y") || y.equals("Y")) {
				int[] request = new int[n];
				System.out.print("要请求的进程名?");
				int p = in.nextInt();
				System.out.print("请输入请求向量:");
				for (int i = 0; i < n; i++) {
					request[i] = in.nextInt();
				}
				bank(p, pNum, request, Need, Available, Allocation, pName);
				System.out.println("是否有请求进程?(输入y确认)");
				y = in.next();
			}

		} else {
			System.out.println("不安全");
		}

	}

	// 安全性算法
	public static boolean security(int pNum, int Available[],
			int Allocation[][], int N[][], String name[]) {
		boolean[] Finish = new boolean[pNum];
		int Work[] = new int[Available.length], Need[][] = N;
		int Work1[][] = new int[pNum][Available.length];
		int WorkA[][] = new int[pNum][Available.length];
		int count = 0;// 进程完成个数
		int number = 0;// 记录圈数
		int find = 0;// 记录是否找到一个合适的进程
		int[] c = new int[pNum];//记录处理的顺序
		for (int i = 0; i < Available.length; i++) {//初始化系统剩下的资源
			Work1[0][i] = Available[i];
			Work[i] = Available[i];
		}

		for (int i = 0; i < Finish.length; i++) {
			Finish[i] = false;
		}

		for (int i = 0; i < pNum; i++) {
			if (Finish[i] == false) {// 找到没有处理的进程
				for (int j = 0; j < Work.length; j++) {
					if (Need[i][j] <= Work[j]) {
						find = 1;
					} else {
						find = 0;
						break;
					}
				}
				if (find == 1) {// 找到合理的进程
					Finish[i] = true;
					c[count] = i;
					count++;
					for (int k = 0; k < Work.length; k++) {// 把上一次的Work给下一个
						Work1[i][k] = Work[k];
						WorkA[i][k] = Work1[i][k] + Allocation[i][k];//
						Work[k] = Work[k] + Allocation[i][k];//
					}
				}
				find = 0;
			}
			if (i == (pNum - 1)) {// 判断是否循环了一圈
				i = -1;// 从新开始循环,对没有处理的进程重新处理
				number++;// 设一个计数器,记录循环圈数
				if (count == pNum) {
					break;
				}
				if (count < number) {// 每循环一次下来,至少有一个进程被处理,否则就是发生死锁
					break;
				}
			}
		}
		for (int k = 0; k < pNum; k++) {//如果找到一个没有完成的进程,则证明是不安全的
			if (Finish[k] == false) {
				return false;
			}
		}
		System.out.print("安全序列为:");
		for (int j = 0; j < c.length; j++) {
			if (j == c.length - 1) {
				System.out.println(name[c[j]]);
			} else {
				System.out.print(name[c[j]] + "->");
			}
		}
		print(Available.length, c, Work1, Need, Allocation, WorkA, name);
		return true;
	}

	public static void bank(int p, int pNum, int request[], int Need[][],
			int Available[], int Allocation[][], String name[]) {// 银行家算法
		int N[][] = Need, A[] = Available;
		for (int i = 0; i < request.length; i++) {
			if(request[i] <= N[p][i]) {
				
				if(request[i] <= A[i]) {
					
				}else {
					System.out.println("请求的资源大于系统拥有的资源,没有足够的资源分配,请等待");
					return;
				}
			}else {
				System.out.println("请求的资源数还需要的最大值,会出错");
				return;
			}
		}
		for (int i = 0; i < request.length; i++) {
			Allocation[p][i] = Allocation[p][i] + request[i];
			A[i] = A[i] - request[i];
			N[p][i] = N[p][i] - request[i];
		}
		boolean s = security(pNum, A, Allocation, N, name);
		if (s) {
			System.out.println("安全");
		} else {
			System.out.println("不安全,请等待");
		}
	}

	public static void print(int l, int c[], int Work[][], int Need[][],
			int Allocation[][], int WA[][], String name[]) {//打印输出处理之后的信息
		int i = 0;
		System.out.println("\tWork\tNeed\tAllocation\tW+A");
		while (i < c.length) {
			System.out.print(name[c[i]] + "\t");
			for (int j = 0; j < l; j++) {
				System.out.print(Work[c[i]][j] + " ");
			}
			System.out.print("\t");
			for (int j = 0; j < l; j++) {
				System.out.print(Need[c[i]][j] + " ");
			}
			System.out.print("\t");
			for (int j = 0; j < l; j++) {
				System.out.print(Allocation[c[i]][j] + " ");
			}
			System.out.print("\t");
			System.out.print("\t");
			for (int j = 0; j < l; j++) {
				System.out.print(WA[c[i]][j] + " ");
			}
			System.out.println();
			i++;
		}
	}
}

运行结果如下:
输入物理块和页面数
输入页面号

运行结果
运行结果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值