1. 程式人生 > >JAVA簡單實現作業系統原理的銀行家演算法

JAVA簡單實現作業系統原理的銀行家演算法

   銀行家演算法是這樣的一種資源分配方法:系統給程序分配資源時,先檢查狀態是否安全,方法是看它是否有足夠的剩餘資源滿足一個距最大需求最近的程序。如果有,那麼分配資源給該程序,然後接著檢查下一個距最大需求最近的程序,如此反覆下去。如果所有的程序都能獲得所需資源,那麼該程序是安全的,最初的程序申請資源可以分配。

假設系統中有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;
			}
			
			
			
		}
	
	}

}

執行結果顯示如下: