银行家算法是这样的一种资源分配方法:系统给进程分配资源时,先检查状态是否安全,方法是看它是否有足够的剩余资源满足一个距最大需求最近的进程。如果有,那么分配资源给该进程,然后接着检查下一个距最大需求最近的进程,如此反复下去。如果所有的进程都能获得所需资源,那么该进程是安全的,最初的进程申请资源可以分配。
假设系统中有3种类型的资源A、B、C和5个进程P1、P2、P3、P4、P5,A资源的数量为10、B资源的数量为5、C资源的数量为7
package com.bran.BankerAlgor;
import java.util.Arrays;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 进程类
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Process {
private String name; //进程名字
private int[] max; //进程的最大需求资源
private int[] allocation; //进程的当前占有资源
private int[] need; //进程的需要资源
private int[] work; //进程当前可分配的资源
private int[] wAndAllocation; // work + allocation
private boolean isFinish; //进程是否能完成
public void printProcess(){ //打印出输入的进程信息
System.out.println(this.getName()+" | "
+Arrays.toString(this.getMax())+" | "
+Arrays.toString(this.getAllocation())+" | "
+Arrays.toString(this.getNeed())+" | ");
}
public void printSafetyProcess(){ //打印出银行家算法分析后的进程情况
System.out.println(this.getName()+" | "
+Arrays.toString(this.getWork())+" | "
+Arrays.toString(this.getNeed())+" | "
+Arrays.toString(this.getAllocation())+" | "
+Arrays.toString(this.getWAndAllocation())+" | "
+this.isFinish());
}
}
package com.bran.BankerAlgor;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Scanner;
/**
*
* 银行家算法类
*
*/
public class BankerAlgor {
private final static int[] total = { 10, 5, 7 };// A资源数量为10,B资源的数量为5,C资源的数量为7
public List<Process> addProcess() { //控制台输入进程信息
List<Process> list = new ArrayList<>();
Scanner sc = new Scanner(System.in);
for (int i = 0; i < 5; i++) {
Process p = new Process();
System.out.println("请输入进程" + (i + 1) + "的名字");
String name = sc.next();
p.setName(name);
System.out.println("请输入进程" + (i + 1) + "的最大占有资源Max");
int[] max = inputArray(sc);
p.setMax(max);
System.out.println("请输入进程" + (i + 1) + "的当前占有资源Allocation");
int[] allocation = inputArray(sc);
p.setAllocation(allocation);
int[] need = inputNeed(p);
p.setNeed(need);
list.add(p);
}
return list;
}
public int[] getAvailable(List<Process> list) { //根据输入的进程来计算剩下的可分配资源
int[] available = new int[3];
List<Process> ls = new ArrayList<>(list);
available[0] = total[0];
available[1] = total[1];
available[2] = total[2];
for (Process p : ls) {
available[0] = available[0] - p.getAllocation()[0];
available[1] = available[1] - p.getAllocation()[1];
available[2] = available[2] - p.getAllocation()[2];
}
return available;
}
public List<Process> bankerAlgor(List<Process> list,int[] available) { //银行家算法
List<Process> listProcess = new ArrayList<>(list);
List<Process> ls = new ArrayList<>();
List<Process> newList = new ArrayList<>();
System.out.println("----------------------------------------------------------------");
System.out.println(" | Work | Need | Allocation| Work + | Finish ");
System.out.println(" | | | | Allocation| ");
System.out.println("----------------------------------------------------------------");
System.out.println(" | [A, B, C] | [A, B, C] | [A, B, C] | [A, B, C] | ");
System.out.println("----------------------------------------------------------------");
while (!listProcess.isEmpty()) {
Iterator<Process> iterator = listProcess.iterator();
while (iterator.hasNext()) {
Process p = iterator.next();
if ((p.getNeed()[0] <= available[0])
&& (p.getNeed()[1] <= available[1])
&& (p.getNeed()[2] <= available[2])) {
ls.add(p);
}
}
if(ls.isEmpty()){
iterator = listProcess.iterator();
while(iterator.hasNext()){
Process p =iterator.next();
p.setFinish(false);
p.printSafetyProcess();
iterator.remove();
}
System.out.println("可用资源不满足任何进程的需要,系统进入不安全状态");
return null;
}
Process p = getNeedMax(ls);
listProcess.remove(p);
p.setWork(Arrays.copyOf(available, available.length));
for(int i=0;i<3;i++){
available[i] +=p.getAllocation()[i];
}
p.setWAndAllocation(Arrays.copyOf(available, available.length));
p.setFinish(true);
newList.add(p);
p.printSafetyProcess();
ls.clear();
}
return newList;
}
public Process getNeedMax(List<Process> list) { //优先算法,优先选择需求资源大的进程
int[] a = new int[list.size()];
for (int i = 0; i < list.size(); i++) {
a[i] = list.get(i).getNeed()[0] + list.get(i).getNeed()[1]
+ list.get(i).getNeed()[2];
}
int j = 0;
if (a.length != 1) {
for (int k = 1; k < a.length; k++) {
if (a[j] <= a[k]) {
j = k;
}
}
}
return list.get(j);
}
public void request(List<Process> list,String name,int[] req){ //进程发起请求资源算法
int[] available=getAvailable(list);
List<Process> rList = new ArrayList<>(list);
for(int i=0;i<rList.size();i++){
if(rList.get(i).getName().equals(name)){
Process p = rList.get(i);
if(judgeProcessRequest(p, req, available)){
int[] allocation = new int[3];
allocation[0]=p.getAllocation()[0]+req[0];
allocation[1]=p.getAllocation()[1]+req[1];
allocation[2]=p.getAllocation()[2]+req[2];
int[] need = new int[3];
need[0]=p.getNeed()[0]-req[0];
need[1]=p.getNeed()[1]-req[1];
need[2]=p.getNeed()[2]-req[2];
p.setNeed(need);
p.setAllocation(allocation);
break;
}else{
System.out.println("申请资源大于需要资源或者大于可分配资源,不能分配");
return;
}
}
}
available=Arrays.copyOf(getAvailable(rList), available.length);
rList=bankerAlgor(rList, available);
if(rList!=null){
System.out.println("所申请的资源可以立即分配给"+name);
}else{
System.out.println("系统不分配资源");
}
}
public boolean judgeProcessRequest(Process p,int[] request,int[] available){
for(int i=0;i<3;i++){
if(request[i]>p.getNeed()[i]||request[i]>available[i]){
return false;
}
}
return true;
}
public List<Process> show() { //显示进程的信息
List<Process> list = addProcess();
System.out.println("----------------------------------------");
System.out.println(" | Max | Allocation| Need |");
System.out.println("----------------------------------------");
System.out.println(" | [A, B, C] | [A, B, C] | [A, B, C] |");
System.out.println("----------------------------------------");
for (int i = 0; i < list.size(); i++) {
Process p = list.get(i);
p.printProcess();
}
System.out.println("Available : " + Arrays.toString(getAvailable(list)));
System.out.println();
return list;
}
public int[] inputArray(Scanner sc) { //控制台输入数组信息
int[] array = new int[3];
for (int i = 0; i < 3; i++) {
array[i] = sc.nextInt();
}
return array;
}
public int[] inputNeed(Process p) { //计算进程的需要资源
int[] need = new int[3];
need[0] = p.getMax()[0] - p.getAllocation()[0];
need[1] = p.getMax()[1] - p.getAllocation()[1];
need[2] = p.getMax()[2] - p.getAllocation()[2];
return need;
}
}
package com.bran.BankerAlgor;
import java.util.List;
import java.util.Scanner;
/**
*
* 测试类
*
*/
public class TestMain {
public static void main(String[] args) {
// TODO 自动生成的方法存根
BankerAlgor banker = new BankerAlgor();
List<Process> list =banker.show();
List<Process> newList=banker.bankerAlgor(list,banker.getAvailable(list));
if(newList!=null){
StringBuilder name = new StringBuilder();
for(int i=0;i<newList.size();i++){
name.append(newList.get(i).getName()).append(" ");
}
System.out.println("存在安全序列有:"+name.toString());
System.out.println("---------------------------------------------");
System.out.println("是否发出资源请求? 1、是 2、否");
Scanner sc = new Scanner(System.in);
int i =sc.nextInt();
switch (i) {
case 1:
System.out.println("输入申请资源的进程名");
String processName = sc.next();
System.out.println("输入申请的资源");
int[] request = banker.inputArray(sc);
banker.request(list, processName, request);
break;
default:
break;
}
}
}
}
运行结果显示如下: