import java.util.ArrayList; |
import java.util.Scanner; |
/** |
* @className Banker |
* @Description 实验二 死锁的避免――银行家算法 |
* @date 2012-4-12 |
*/ |
public class Banker { |
int available[] = new int [] { 3 , 3 , 2 }; // 可得到的资源 |
int max[][] = new int [][] { { 7 , 5 , 3 }, { 3 , 2 , 2 }, { 9 , 0 , 2 }, |
{ 2 , 2 , 2 }, { 4 , 3 , 3 } }; // 每个进程最大资源数 |
int allocation[][] = new int [][] { { 0 , 1 , 0 }, { 2 , 0 , 0 }, { 3 , 0 , 2 }, |
{ 2 , 1 , 1 }, { 0 , 0 , 2 } }; // 每个进程目前拥有的资源数 |
int need[][] = new int [][] { { 7 , 4 , 3 }, { 1 , 2 , 2 }, { 6 , 0 , 0 }, |
{ 0 , 1 , 1 }, { 4 , 3 , 1 } }; // 每个进程需要的资源数 |
ArrayList<Integer> arrayList = new ArrayList<Integer>(); |
private void showData() // 展示数据输出每个进程的相关数据 |
{ |
System.out.println( "进程个数:5 资源个数:3" ); |
System.out.println( "可用资源向量:" ); |
for ( int i = 0 ; i < available.length; i++) { |
System.out.print(available[i] + "\t" ); |
} |
System.out.print( "\n最大需求矩阵Max:\n" ); |
for ( int i = 0 ; i < 5 ; i++) { |
for ( int j = 0 ; j < 3 ; j++) { |
System.out.print( " " + max[i][j] + "\t" ); |
} |
System.out.println(); |
} |
System.out.print( "\n已分配矩阵Allocation:\n" ); |
for ( int i = 0 ; i < 5 ; i++) { |
for ( int j = 0 ; j < 3 ; j++) { |
System.out.print( " " + allocation[i][j] + "\t" ); |
} |
System.out.println(); |
} |
System.out.print( "\n需求矩阵Need:\n" ); |
for ( int i = 0 ; i < 5 ; i++) { |
for ( int j = 0 ; j < 3 ; j++) { |
System.out.print( " " + need[i][j] + "\t" ); |
} |
System.out.println(); |
} |
} |
private boolean change( int inRequestNum, int inRequest[]) // 分配数据 |
{ |
int requestNum = inRequestNum; |
int request[] = inRequest; |
// for(int i=0;i<3;i++)System.out.println("修改前available"+available[i]); |
if (!(request[ 0 ] <= need[requestNum][ 0 ] |
&& request[ 1 ] <= need[requestNum][ 1 ] && request[ 2 ] <= need[requestNum][ 2 ])) { |
System.out.println( "出错:申请的资源大于需求值" ); |
return false ; |
} |
if ((request[ 0 ] <= available[ 0 ] && request[ 1 ] <= available[ 1 ] && request[ 2 ] <= available[ 2 ]) == false ) { |
System.out.println( "出错:无足够资源分配" ); |
return false ; |
} |
System.out.println( "开始执行银行家算法..." ); |
for ( int i = 0 ; i < 3 ; i++) // 试分配数据给请求的线程 |
{ |
available[i] = available[i] - request[i]; |
allocation[requestNum][i] = allocation[requestNum][i] + request[i]; |
need[requestNum][i] = need[requestNum][i] - request[i]; |
} |
System.out.println( "试分配完成...\n" ); |
// for(int i=0;i<3;i++)System.out.println("修改后available"+available[i]); |
boolean flag = checkSafe(available[ 0 ], available[ 1 ], available[ 2 ]); // 进行安全性检查并返回是否安全 |
// System.out.println("安全性检查后"+flag); |
if (flag == true ) { |
System.out.print( "找到一个安全序列:" ); |
System.out.print(arrayList); |
System.out.println( "\n已通过安全性测试!\n" ); |
System.out.println( "资源分配完成。" ); |
return true ; |
} else // 不能通过安全性检查 恢复到未分配前的数据 |
{ |
System.out.println( "不能够安全分配,正在恢复..." ); |
for ( int i = 0 ; i < 3 ; i++) { |
available[i] = available[i] + request[i]; |
allocation[requestNum][i] = allocation[requestNum][i] |
- request[i]; |
need[requestNum][i] = need[requestNum][i] + request[i]; |
} |
System.out.println( "恢复完成。" ); |
return false ; |
} |
} |
private boolean checkSafe( int a, int b, int c) // 安全性检查 |
{ |
System.out.println( "进入安全性测试!" ); |
arrayList.clear(); // 先清空安全序列 |
int work[] = new int [ 3 ]; |
work[ 0 ] = a; |
work[ 1 ] = b; |
work[ 2 ] = c; |
int i = 0 ; |
boolean finish[] = new boolean [ 5 ]; |
while (i < 5 ) // 寻找一个能够满足的认为完成后才去执行下一进程 |
{ |
if (finish[i] == false && need[i][ 0 ] <= work[ 0 ] |
&& need[i][ 1 ] <= work[ 1 ] && need[i][ 2 ] <= work[ 2 ]) { // 找到满足的修改work值,然后i=0,重新从开始的为分配的中寻找 |
arrayList.add(i); |
for ( int m = 0 ; m < 3 ; m++) |
work[m] = work[m] + allocation[i][m]; |
finish[i] = true ; |
i = 0 ; |
} else |
// 如果没有找到直接i++ |
i++; |
} |
for (i = 0 ; i < 5 ; i++) // 通过finish数组判断是否都可以分配 |
{ |
if (finish[i] == false ) |
return false ; |
} |
return true ; |
} |
public static void main(String[] args) { |
Banker bank = new Banker(); |
bank.showData(); |
int request[] = new int [ 3 ]; |
int requestNum; |
Scanner s; |
String choice = new String(); |
while ( true ) // 循环进行分配 |
{ |
s = new Scanner(System.in); |
System.out.println( "请输入要请求的进程号(0--4):" ); |
requestNum = s.nextInt(); |
System.out.println( "输入请求资源的数目:按照这样的格式输入x x x:" ); |
for ( int i = 0 ; i < 3 ; i++) { |
request[i] = s.nextInt(); |
} |
bank.change(requestNum, request); |
System.out.println( "\n需要继续吗? (y-继续/n-终止)" ); |
choice = s.next(); |
while ( true ) { |
if (choice.equalsIgnoreCase( "n" )) { |
System.exit( 1 ); |
} else if (choice.equalsIgnoreCase( "y" )) { |
break ; |
} else { |
System.out.println( "输入错误,请重试..." ); |
System.out.println( "\n需要继续吗? (y-继续/n-终止)" ); |
choice = s.next(); |
} |
} |
} |
} |
} |