银行家问题(java实现)

10 篇文章 0 订阅
3 篇文章 1 订阅

引用来自  https://blog.csdn.net/u012116457/article/details/25384571

首先,介绍一下银行家算法问题的产生与它的重大意义。

银行家算法(Banker's Algorithm)是一个避免死锁(Deadlock)的著名算法,是由艾兹格·迪杰斯特拉在1965年为T.H.E系统设计的一种避免死锁产生的算法。它以银行借贷系统的分配策略为基础,判断并保证系统的安全运行。

安全状态:如果存在一个由系统中所有进程构成的安全序列P1,…,Pn,则系统处于安全状态。安全状态一定是没有死锁发生。

不安全状态:不存在一个安全序列。不安全状态不一定导致死锁

也就是说,系统程序的运行时期,占用相同寄存器之类的共有资源时,需要找到一条不唯一的执行串链。如果这么一条可执行串链存在,那么系统就不会发生死锁问题,如果找不到。那么系统必定会产生死锁问题。

百度百科解释,著名银行家算法的的数据结构。

1)可利用资源向量Available

是个含有m个元素的数组,其中的每一个元素代表一类可利用的资源数目。如果Available[j]=K,则表示系统中现有Rj类资源K个。

2)最大需求矩阵Max

这是一个n×m的矩阵,它定义了系统中n个进程中的每一个进程对m类资源的最大需求。如果Max[i,j]=K,则表示进程i需要Rj类资源的最大数目为K。

3)分配矩阵Allocation

这也是一个n×m的矩阵,它定义了系统中每一类资源当前已分配给每一进程的资源数。如果Allocation[i,j]=K,则表示进程i当前已分得Rj类资源的 数目为K。

4)需求矩阵Need。

这也是一个n×m的矩阵,用以表示每一个进程尚需的各类资源数。如果Need[i,j]=K,则表示进程i还需要Rj类资源K个,方能完成其任务。

Need[i,j]=Max[i,j]-Allocation[i,j]

import java.util.Scanner;

public class Bank {

	
	static int available[]=new int[3];         //资源数
	static int max[][]=new int[5][3];          //最大需求
	static int allocation[][]=new int[5][3];   //分配
	static int need[][]=new int[5][3];         //需求
	static int request[]=new int[3];           //存放请求
	Scanner scanner=new Scanner(System.in);
	int thread;  //线程
	
	//用户输入要申请资源的线程和申请的资源,并进行判断
		public void getThread(){
			System.out.println("请输入申请资源的线程");
			int thread=scanner.nextInt();     //线程
			if(thread<0||thread>4){
				System.out.println("该线程不存在,请重新输入");
				getThread();
			}else{
				this.thread=thread;
				System.out.println("请输入申请的资源(三种,若某种资源不申请则填0)");
				for(int i=0;i<3;i++){
					request[i]=scanner.nextInt();
				}
				if(request[0]>need[thread][0]||request[1]>need[thread][1]||request[2]>need[thread][2]){
					System.out.println(thread+"线程申请的资源超出其需要的资源,请重新输入");
					getThread();
				}else{
					if(request[0]> available[0]||request[1]> available[1]||request[2]> available[2]){
						System.out.println(thread+"线程申请的资源大于系统资源,请重新输入");
						getThread();
					}
				}
				changeData(thread);
				if(check(thread)){
					 getThread();
				}else{
					recoverData(thread);
					getThread();
				}
	 
			}
		}
		
		 //thread线程请求响应后,试探性分配资源
		 public void changeData(int thread){
			 for(int i=0;i<3;i++){
				 //重新调整系统资源数
				 available[i]-=request[i];
				 //计算各个线程拥有资源
				 allocation[thread][i]+=request[i];
				 //重新计算需求
				 need[thread][i]-=request[i];
			 }		 
	   }
	  
		   //安全性检查为通过,分配失败时调用,恢复系统原状		 
		    public void recoverData(int thread){
			   for(int i=0;i<3;i++){
					 //重新调整系统资源数
					 available[i]+=request[i];
					 //计算各个线程拥有资源
					 allocation[thread][i]-=request[i];
					 //重新计算需求
					 need[thread][i]+=request[i];
			  }	
		    }
		    
		//对线程thread安全性检查
		 public boolean check(int thread){
			 boolean finish[]=new boolean[5];
			 int work[]=new int[3];
			 int queue[]=new int[5];   //由于存放安全队列
			 int k=0;//安全队列下标
			 int j;  //要判断的线程
			 int i;
			 //是否分配的标志
			 for(i=0;i<5;i++)
				 finish[i]=false;
			 j=thread;
			 for(i=0;i<3;i++){
				 work[i]=available[i];
			 }
			 while(j<5){
				 for( i=0;i<3;i++){	
					 if(finish[j]){
						 j++;
						 break;
					 }else if(need[j][i]>work[i]){
						 j++;
						 break;
					 }else if(i==2){
						 for(int m=0;m<3;m++){
							 work[m]+=allocation[j][m];
						 }
						 finish[j]=true;
						 queue[k]=j;
						 k++;
						 j=0;   //从最小线程再开始判断
					 }
				 }
			 }
			 
			 //判断是否都属于安全状态
			 for(int p=0;p<5;p++){
				 if(finish[p]=false){
					 System.out.println("系统不安全,资源申请失败");
					 return false;
				 }
			 }
			 System.out.println("资源申请成功,安全队列为:");
			 for(int q=0;q<5;q++){
				 System.out.println(queue[q]);
			 } 
			 return true;
		 }
		 //打印need和available,需要时调用
		  public void showData(){
			  System.out.println("need");
			  for(int i=0;i<5;i++){
				  for(int j=0;j<3;j++){
					  System.out.print(need[i][j]+"     ");
				  }
			  }
			     System.out.println("available");
				  for(int j=0;j<3;j++){
					  System.out.print(available[j]+"     ");
				  }
		  }
	   public static void main(String[] args) {
		  Bank bk=new Bank();
		  bk.getThread();
	 
		}
	 
	

}

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值