JAVA簡單實現作業系統原理的銀行家演算法
阿新 • • 發佈:2018-12-17
銀行家演算法是這樣的一種資源分配方法:系統給程序分配資源時,先檢查狀態是否安全,方法是看它是否有足夠的剩餘資源滿足一個距最大需求最近的程序。如果有,那麼分配資源給該程序,然後接著檢查下一個距最大需求最近的程序,如此反覆下去。如果所有的程序都能獲得所需資源,那麼該程序是安全的,最初的程序申請資源可以分配。
假設系統中有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; } } } }
執行結果顯示如下: