最近几天看完银行家算法后,决定自己动手用java实现该算法。本文实现了银行家算法的关键方法:判断某一次资源分配是否会造成死锁的发生。
关于银行家算法的思想,可以参考这篇文章 http://zh.wikipedia.org/wiki/%E9%93%B6%E8%A1%8C%E5%AE%B6%E7%AE%97%E6%B3%95
好了,不多说了,直接上代码
/**
* 银行家算法,避免死锁
* 2014-9-12
* @author knight_coder
*
*/
public class Banker {
Banker banker = new Banker(4, 4);//4个进程:编号0-3;4种资源,编号0-3
//初始化系统资源数目
int available[] = new int[]{1,5,2,0};
int need[][] = new int[][]{{0,6,4,2},{0,5,1,0},{0,0,0,2},{0,7,5,0}};
int allocation[][] = new int[][]{{0,0,1,4},{1,4,3,2},{1,3,5,4},{1,0,0,0}};
banker.setAvailable(available);
banker.setNeed(need);
banker.setAllocation(allocation);
//判断是否发生死锁:给0号进程分配1号资源,数量是5
//结果:发生死锁
banker.judge(0, 1, 5);
//判断是否发生死锁:给0号进程分配1号资源,数量是5
//结果:不会发生死锁
banker.judge(1, 1, 5);
/**
* 构造函数
* @param threads 并发线程数
* @param resources 资源种类
*/
public Banker(int threads, int resources) {
this.threads = threads;
this.resources = resources;
allocation = new int[threads][resources];
need = new int[threads][resources];
available = new int[resources];
}
/**
* 初始化系统拥有的各类资源的数量
* @param i
* @param j
*/
public void initializeResources(int i, int j) {
available[i] = j;
}
/**
* 获取系统拥有的各类资源的数量
* @return
*/
public int[] getAvailable() {
return available;
}
/**
* 设置系统拥有的各类资源的数量
* @param available
*/
public void setAvailable(int[] available) {
this.available = available;
}
/**
* 返回每个线程已经获取的资源数
* @return
*/
public int[][] getAllocation() {
return allocation;
}
/**
* 设置每个线程已经获取的资源数
*/
public void setAllocation(int[][] allocation) {
this.allocation = allocation;
}
/**
* 获取每个进程还需要的资源数目
* @return
*/
public int[][] getNeed() {
return need;
}
/**
* 设置每个进程还需要的资源数目
* @param need
*/
public void setNeed(int[][] need) {
this.need = need;
}
/**
* 判断如果给进程i分配数量为mount的资源j,是否会发生死锁
* @param i
* @param j
* @return
*/
public boolean judge(int i, int j, int mount){
//创建数组副本
int need[][] = this.need.clone();
int allocation[][] = this.allocation.clone();
int available[] = this.available.clone();
if(need[i][j] < mount){
System.out.println("进程" + i + "不需要那么多资源" + j + ",分配失败");
return false;
}else if(available[j] < mount){
System.out.println("剩余的资源" + j + "数量不足,分配失败");
return false;
}else{
need[i][j] -= mount;//更新进程i需要资源j的数量
allocation[i][j] += mount;//更新已分配资源的数量
available[j] -= mount;//更新剩余资源数
boolean end = false;//判断循环是否结束
boolean success[]= new boolean[threads]; //进程是否可获得需要的全部资源。获取成功后,应释放已获取的全部资源
while(!end){
end = true;
for(int k = 0; k < threads; k++) {
if(success[k])//进程k已结束
continue;
int g = 0;
for(; g < resources; g++) {
if(need[k][g] > available[g])
break;
}
if(g == resources){//进程k可获得需要的全部资源
success[k] = true;//标识进程k已结束
end = false;
//获取成功后,应释放已获取的全部资源
for(g = 0; g < resources; g++)
available[g] += allocation[k][g];
}
}
}
for(boolean b : success){//如果有进程未能结束,表示此次资源分配会发生死锁
if(!b){
System.out.println("发生死锁");
return false;
}
}
System.out.println("资源分配成功");
return true;//表示此次资源分配不会发生死锁
}
}
}