一 银行家算法简介
避免死锁
二 代码实现
package How_2;
import java.awt.DisplayMode;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Scanner;
import javax.imageio.stream.MemoryCacheImageInputStream;
import org.omg.CORBA.Request;
class resource //资源类
{
int []v;
int []m; // 当前剩余资源数组
public resource(int[] v,int []m)
{
this.v=v;
this.m=m;
}
}
class process //进程类
{
static resource myResource;
int id; //进程标识
int []max; //最大需求量
int []allocation; //已分配量
int []need; //剩余需求量
public process(resource myResource,int []max,int []allocation,int id)
{
this.myResource=myResource;
this.max=max;
this.allocation=allocation;
this.need=new int[max.length];
this.id=id;
for(int i=0; i<this.need.length; i++)
{
this.need[i]=this.max[i]-allocation[i];
}
}
}
class banker //设置银行家
{
int []Request;
LinkedList<process> Process;
int p;
process thisprocess;
String safeQueue=""; //安全序列
public banker(LinkedList myProcess) //类资源
{
this.Process=myProcess;
}
public void request(int p,int []Request) //资源请求
{
this.Request=Request;
thisprocess=(process)Process.get(p);
//判断请求合理性
this.p=p;
if(cheekM()&&cheekNeed())
{
//假设可以分配
//更新m向量
//不足:对矩阵运算符的重载
for(int i=0; i<thisprocess.myResource.m.length; i++)
{
thisprocess.myResource.m[i]-=Request[i];
thisprocess.need[i]-=Request[i];
thisprocess.allocation[i]+=Request[i];
// System.out.println("77777777777777");
// System.out.println("thisprocess.myResource.m["+i+"]"+thisprocess.myResource.m[i]);
}
if(cheekSafe())
{
System.out.println("请求成功!");
System.out.println("安全序列为:");
System.out.println(safeQueue);
safeQueue="";
//更新状态
//更改need
//更改allocation
}
else //不安全,拒绝分配
{
System.out.println("此状态不安全,无法分配!!!");
for(int i=0; i<thisprocess.myResource.m.length; i++) //恢复资源状态
{
thisprocess.myResource.m[i]+=Request[i];
thisprocess.need[i]+=Request[i];
thisprocess.allocation[i]-=Request[i];
}
}
}
display();
}
public boolean cheekM() //检查当前资源是否满足要求,充足
{
boolean agree=true;
// System.out.println("5555555555555555");
for(int i=0; i<thisprocess.myResource.m.length; i++)
{
if(Request[i]>thisprocess.myResource.m[i]) //请求不合理
{
agree=false;
System.out.println("资源不足,拒绝请求!!!");
break;
}
// System.out.println("Request["+i+"]="+Request[i]);
// System.out.println(""+thisprocess.myResource.m[i]);
}
return agree;
}
public boolean cheekNeed() //检查请求是否合理
{
boolean agree=true;
for(int i=0; i<thisprocess.need.length; i++)
{
if(Request[i]>thisprocess.need[i]) //请求不合理
{
agree=false;
System.out.println("请求非法!!!");
break;
}
// System.out.println("66666666666666666666666666");
System.out.println("Request["+i+"]="+Request[i]);
System.out.println(""+thisprocess.need[i]);
}
return agree;
}
public boolean cheekSafe() //检查安全状态 核心代码
{
boolean agree=false;
int []temp_m=new int [thisprocess.myResource.m.length];
//System.out.println("复制数组");
//复制数组
temp_m=Arrays.copyOf(thisprocess.myResource.m, thisprocess.myResource.m.length);
//复制链表 形成动态数组,这是银行家算法的关键
//结束条件 数组变空 状态安全
//结束条件 类似冒泡算法 只要有一次比较完temp_process的所以元素儿没有比m向量小的,此状态不安全
//安全判断 v=m 资源可以全部收回
LinkedList<process> temp_process=new LinkedList<process>();
for(int i=0; i<Process.size(); i++)
{
temp_process.add(Process.get(i));
}
// System.out.println("进程"+1+":");
// process itProcess=temp_process.get(1);
// System.out.println("max[i]");
// for(int ele:itProcess.max)
// {
// System.out.print(ele+" ");
// }
// System.out.println();;
// for(int ele:temp_m)
// {
// System.out.print(""+ele+" ");
// }
// System.out.println();
boolean count=true;
do
{
int i=0;
count=false;
for(i=0; i<temp_process.size(); i++)
{
// System.out.println("+++++++++++++++++++++++++++");
boolean yes=true; //比较need
process itProcess1=(process) temp_process.get(i);
// System.out.println("进程"+itProcess1.id);
//探查need矩阵
for(int j=0; j<temp_m.length; j++)
{
if(itProcess1.need[j]>temp_m[j])
{
yes=false;
// System.out.println("break");
break;
}
// System.out.println("itProcess.need["+j+"]"+itProcess1.need[j]);
// System.out.println("temp_m["+j+"]"+temp_m[j]);
}
// System.out.println("max[i]");
// for(int ele:itProcess1.max)
// {
// System.out.print(ele+" ");
// }
// System.out.println();
// System.out.println("+++++++++++++++++++++++++++");
if(yes) //need矩阵探查满足,开始回收此进程的allocation矩阵
{
// System.out.println("kkkkkkkkkkkkkkkkkkkkkkk");
for(int k=0; k<temp_m.length; k++)
{
temp_m[k]+=itProcess1.allocation[k]; //收回分配
}
// for(int ele:temp_m)
// {
// System.out.print(""+ele+" ");
// }
safeQueue+=""+temp_process.get(i).id;
count=true;
temp_process.remove(i);
i=-1;
// for循环重头开始 令i=-1 而不是让i=0
// 否则会导致资源无法遍历 进程1
}
}
}
while(count&&!temp_process.isEmpty()); //存在安全状态等价条件
// if(Arrays.equals(temp_m, thisprocess.myResource.v)) //分配全部收回
// 数组相等
if(count)
{
agree=true;
}
return agree;
}
public void display()
{
System.out.println("m[i]:");
for(int ele:thisprocess.myResource.m)
{
System.out.print(ele+" ");
}
System.out.println();
for(int i=0; i<Process.size(); i++)
{
process itProcess=Process.get(i);
System.out.println("进程"+itProcess.id+":");
System.out.println("max[i]");
for(int ele:itProcess.max)
{
System.out.print(ele+" ");
}
System.out.println();
System.out.println("allocation[i]");
for(int ele:itProcess.allocation)
{
System.out.print(ele+" ");
}
System.out.println();
System.out.println("need[i]");
for(int ele:itProcess.need)
{
System.out.print(ele+" ");
}
System.out.println();
}
}
}
public class bin_1
{
public static void main(String[] args)
{
int v[]={10,5,7}; //总的资源数
int m[]={3,2,2}; //剩余资源
resource myResource=new resource(v,m);
LinkedList<process> myProcesses=new LinkedList<process>();
int max0[]={7,5,3}; //最大需求举证
int allocation0[]={0,1,0}; //已分配资源
process process0=new process(myResource, max0, allocation0,1);
myProcesses.add(process0);
int max1[]={3,2,2};
int allocation1[]={2,1,0};
process process1=new process(myResource, max1, allocation1,2);
myProcesses.add(process1);
int max2[]={9,0,2};
int allocation2[]={3,0,2};
process process2=new process(myResource, max2, allocation2,3);
myProcesses.add(process2);
int max3[]={2,2,2};
int allocation3[]={2,1,1};
process process3=new process(myResource, max3, allocation3,4);
myProcesses.add(process3);
int max4[]={4,3,3};
int allocation4[]={0,0,2};
process process4=new process(myResource, max4, allocation4,5);
myProcesses.add(process4);
banker myBanker=new banker(myProcesses);
myBanker.display();
Scanner how=new Scanner(System.in);
int []zero={0,0,0};
while(true)
{
int []myRequest=new int[m.length];
int p;
System.out.println("请输入请求进程:");
p=how.nextInt();
p--; //下标从0开始
System.out.println("请输入请求资源:");
for(int i=0; i<myRequest.length; i++)
{
myRequest[i]=how.nextInt();
}
myBanker.request(p, myRequest);
}
}
}
三 运行结果
m[i]:
3 2 2
进程1:
max[i]
7 5 3
allocation[i]
0 1 0
need[i]
7 4 3
进程2:
max[i]
3 2 2
allocation[i]
2 1 0
need[i]
1 1 2
进程3:
max[i]
9 0 2
allocation[i]
3 0 2
need[i]
6 0 0
进程4:
max[i]
2 2 2
allocation[i]
2 1 1
need[i]
0 1 1
进程5:
max[i]
4 3 3
allocation[i]
0 0 2
need[i]
4 3 1
请输入请求进程:
2
请输入请求资源:
1
0
2
Request[0]=1
1
Request[1]=0
1
Request[2]=2
2
请求成功!
安全序列为:
24135
m[i]:
2 2 0
进程1:
max[i]
7 5 3
allocation[i]
0 1 0
need[i]
7 4 3
进程2:
max[i]
3 2 2
allocation[i]
3 1 2
need[i]
0 1 0
进程3:
max[i]
9 0 2
allocation[i]
3 0 2
need[i]
6 0 0
进程4:
max[i]
2 2 2
allocation[i]
2 1 1
need[i]
0 1 1
进程5:
max[i]
4 3 3
allocation[i]
0 0 2
need[i]
4 3 1
请输入请求进程:
四 总结收获
1. 程序架构
class resource //资源类
class process //进程类
class banker //设置银行家
逐渐走入面向对象编程的方向
2. 核心代码 使用过了Linkledist
3. 核心代码 模仿改进版的冒泡排序
五 不足
.
矩阵运算都使用for循环,应当考虑重载
其次应该改进进程类的数据结构,使其拥有
更强的健壮性
可以考虑做gui界面