2021-03-03 Java代码模拟银行家算法

银行家算法 专栏收录该内容
1 篇文章 0 订阅

Java代码模拟操作系统银行家算法

实验题目

模拟使用银行家算法判断系统的状态。

目的

银行家算法是操作系统中避免死锁的算法,本实验通过对银行家算法的模拟,加强学生对该算法的理解与应用。

模拟环境

硬件:pc 机及其兼容机。
软件:Windows OS,MS—DOS OS,Turbo C 或 C++、VC++等

内容

1.建立 T0 时刻的资源分配表,初始化。
2.设计银行家算法,输入一个进程的资源请求,按银行家算法步骤进行检查。
3.设计安全性算法,检查某时系统是否安全。
4.设计显示函数,显示资源分配表,安全分配序列。

算法流程图

Created with Raphaël 2.2.0 初始化T0时刻资源分配表 资源申请 读入一个进程的申请 按银行家算法检查 利用安全算法检查此时是否安全 安全? 输出安全序列 显示:此次资源请求成功 修改资源分配表 结束 yes no

程序清单

import java.util.Scanner;

import java.util.Scanner;

/** 银行家算法主体类: */
public class Bank 
{
	/** 分配资源的方法:将进程的资源请求进行处理 */
	public void BankAlgorithm() 
	{
		/** 初始化系统已有的资源 + 五个进程的当前信息 */
		// 五个进程对象(输入每个进程对象的名称\所需的最大资源\已分配的资源\还需要的资源)
		Processor processor[] = new Processor[5];
		/** 第一组测试数据: */
		processor[0] = new Processor("P0", 5, 7, 3, 1, 0, 0, 4, 7, 3);
		processor[1] = new Processor("P1", 2, 3, 2, 0, 2, 0, 2, 1, 2);
		processor[2] = new Processor("P2", 0, 9, 2, 0, 3, 2, 0, 6, 0);
		processor[3] = new Processor("P3", 2, 2, 2, 1, 2, 1, 1, 0, 1);
		processor[4] = new Processor("P4", 3, 4, 3, 0, 0, 2, 3, 4, 1);
		
		/** 第二组测试数据: 
		processor[0] = new Processor("P0", 5, 7, 3, 1, 0, 0, 4, 7, 3);
		processor[1] = new Processor("P1", 2, 3, 2, 0, 2, 0, 2, 1, 2);
		processor[2] = new Processor("P2", 0, 9, 2, 0, 3, 2, 0, 6, 0);
		processor[3] = new Processor("P3", 2, 2, 2, 1, 2, 1, 1, 0, 1);
		processor[4] = new Processor("P4", 3, 4, 3, 3, 3, 3, 0, 1, 0);*/
		

		// 一个资源对象(表示当系统拥有的资源)
		Sources sources = new Sources(3, 3, 2);

		System.out.println("当前系统可分配资源为:");
		System.out.println("A: " + sources.A + "\tB: " + sources.B + "\tC: " + sources.C);
		System.out.println("----------------------------进程状态" + "------------------------------");
		System.out.println("P(进程号)" + "\t" + "Max(所需最大资源)" + "\t" + "Allocation(已分配资源)" + "\t" + "Need(还需要的资源数量)");
		System.out.println("" + "\t" + "A B C" + "\t\t" + "A B C" + "\t\t\t" + "A B C");
		for (int i = 0; i < 5; i++)
		{
			processor[i].ShowProcessor();
		}
		System.out.println("-----------------------------------------------------------------\n");

		while (true)
		{
			System.out.println("开始进程资源分配:");

			// 输入要请求的进程号及其要请求的资源数目
			Scanner scan = new Scanner(System.in);
			System.out.println("请输入要请求的进程号(0-4): ");
			int RequestProcessorNum = scan.nextInt();
			System.out.println("请输入要为该进程请求的资源数目(A、B、C): ");
			int a, b, c;
			a = scan.nextInt();
			b = scan.nextInt();
			c = scan.nextInt();
			Sources RequestSources = new Sources(a, b, c);

			// 当初始时第一个进程请求完毕后,需要做判断和改值
			// 1.判断是不是保证请求的每个资源数量是小于等于该进程还需要的资源数量的
			if (RequestSources.A > processor[RequestProcessorNum].need.A
					|| RequestSources.B > processor[RequestProcessorNum].need.B
					|| RequestSources.C > processor[RequestProcessorNum].need.C) {
				System.out.println("出现错误: 请求的资源超过了该进程所需要的资源");
				System.out.println("退出系统");
				System.exit(-1);
			}
			// 2.判断请求的资源是不是小于等于当前所拥有的资源
			if (RequestSources.A > sources.A || RequestSources.B > sources.B || RequestSources.C > sources.C) {
				System.out.println("出现错误: 请求的资源超过了系统此时拥有的资源");
				System.out.println("退出系统(等待其他进程释放资源)");
				System.exit(-1);
			}

			// 工作资源(实时记录当前系统资源数量)
			Sources Work = new Sources(3,3,2);

			//因为已经有进程请求了分配资源,假设可以进行这次的资源请求,所以需要改值
			processor[RequestProcessorNum].allocation.A += RequestSources.A;
			processor[RequestProcessorNum].allocation.B += RequestSources.B;
			processor[RequestProcessorNum].allocation.C += RequestSources.C;
			processor[RequestProcessorNum].need.A -= RequestSources.A;
			processor[RequestProcessorNum].need.B -= RequestSources.B;
			processor[RequestProcessorNum].need.C -= RequestSources.C;
			Work.A -= RequestSources.A;
			Work.B -= RequestSources.B;
			Work.C -= RequestSources.C;
			
			//已经做出了资源请求并且改了值,判断是不是存在安全序列
			boolean isExistSafeQueue = true;
			String[] safeQueue = new String[5];
			int index = 0;
			while (true) 
			{
				boolean find = false;
				for (int i = 0; i < 5; i++) 
				{
					if (processor[i].Finish == false)// 该进程没有分配资源
					{
						boolean flag = true;// 看系统当前资源是不是>=该进程需要的资源
						if (Work.A < processor[i].need.A) 
						{
							flag = false;
						}
						if (Work.B < processor[i].need.B) 
						{
							flag = false;
						}
						if (Work.C < processor[i].need.C) 
						{
							flag = false;
						}
						if (flag == true)
						{
							//System.out.println("此时进程"+i+"可以被分配资源"); 
							
							// 满足三个资源的条件,可以进行资源的分配,当前系统的资源要+上该进程释放的资源
							Work.A += processor[i].allocation.A;
							Work.B += processor[i].allocation.B;
							Work.C += processor[i].allocation.C;

							//System.out.println("分配资源后work数组等于="+Work.A+","+Work.B+","+Work.C);
							
							processor[i].Finish = true;
							
							// 安全序列中加入这个进程
							safeQueue[index++] = "P" + i;

							// 标记find
							find = true;
						}
					}
				}
				if (find == false) 
				{
					for (int i = 0; i < 5; i++) 
					{
						if (processor[i].Finish == false)
						{
							isExistSafeQueue = false;
							System.out.println("出现进程之间的死锁,也就是找不到安全序列");
							break;
						}
					}
					break;
				}
			}
			// 如果存在安全序列
			if (isExistSafeQueue == true) 
			{
				System.out.println("能够对进程安全分配资源");
				System.out.println("安全序列如下:");
				for (int i = 0; i < 5; i++) 
				{
					System.out.print(safeQueue[i] + " ");
				}
				System.out.println();

				//已经判断能够形成安全序列,表示该进程的资源请求成功,此时不需要改变进程的值只要改变sources的值解
				sources.A -= RequestSources.A;
				sources.B -= RequestSources.B;
				sources.C -= RequestSources.C; 
				
				System.out.println("\n系统分配资源后:");
				System.out.println("当前系统可分配资源为:");
				System.out.println("A: " + sources.A + "\tB: " + sources.B + "\tC: " + sources.C);
				System.out.println("----------------------------进程状态" + "------------------------------");
				System.out.println(
						"P(进程号)" + "\t" + "Max(所需最大资源)" + "\t" + "Allocation(已分配资源)" + "\t" + "Need(还需要的资源数量)");
				System.out.println("   " + "\t" + "A B C" + "\t\t" + "A B C" + "\t\t\t" + "A B C");
				for (int i = 0; i < 5; i++)
				{
					processor[i].ShowProcessor();
				}
				System.out.println("-----------------------------------------------------------------\n");

			} 
			else 
			{
				System.out.println("不能够对进程进行安全的资源分配");
				
				//已经判断不能够形成安全序列,表示该进程的资源请求失败,因为之前已经修改了值,所以要改回来
				processor[RequestProcessorNum].allocation.A -= RequestSources.A;
				processor[RequestProcessorNum].allocation.B -= RequestSources.B;
				processor[RequestProcessorNum].allocation.C -= RequestSources.C;
				processor[RequestProcessorNum].need.A += RequestSources.A;
				processor[RequestProcessorNum].need.B += RequestSources.B;
				processor[RequestProcessorNum].need.C += RequestSources.C;
				
				System.out.println("当前系统可分配资源为:");
				System.out.println("A: " + sources.A + "\tB: " + sources.B + "\tC: " + sources.C);
				System.out.println("----------------------------进程状态" + "------------------------------");
				System.out.println(
						"P(进程号)" + "\t" + "Max(所需最大资源)" + "\t" + "Allocation(已分配资源)" + "\t" + "Need(还需要的资源数量)");
				System.out.println("   " + "\t" + "A B C" + "\t\t" + "A B C" + "\t\t\t" + "A B C");
				for (int i = 0; i < 5; i++)
				{
					processor[i].ShowProcessor();
				}
				System.out.println("-----------------------------------------------------------------\n");
				
			}
	
			System.out.println("是否还需要测试该算法(yes/no):");
			String ask = scan.next();
			if (ask.equals("no")) 
			{
				break;
			}
		}
	}
}

package com.mao.bank;



/** 用于测试和调试银行家算法 */
public class Main {
    public static void main(String[] args) {

        /** 开始调用银行家算法进行资源请求(判断是不是能形成一个安全序列) */
        //银行家对象
        Bank banker = new Bank();

        //通过对象调用银行家算法
        banker.BankAlgorithm();
    }
}

package com.mao.bank;

public class Processor {
	
  	/** 四个字段 */
	private String name;//进程名字
	Sources max;//进程所需要的最大资源
	Sources allocation;//当前进程已经分配的资源数
	Sources need;//当前进程还需要多少资源(max-allocation)
	public boolean Finish = false;//判断进程是否结束
	
	public Processor(String name, int max_a,int max_b,int max_c,int all_a,int all_b,int all_c,int need_a,int need_b,int need_c) 
	{
		this.name = name;
		max = new Sources(max_a,max_b,max_c);
		allocation = new Sources(all_a,all_b,all_c);
		need = new Sources(need_a,need_b,need_c);
	}
	
	public void ShowProcessor()
	{
		//打印出进程的信息
		System.out.println(name+"\t"+max.toString()+"\t\t"+allocation.toString()+"\t\t\t"+need.toString());
	}
}


package com.mao.bank;

/** 资源类 */
public class Sources {

	/** 三个字段分别表示A.B.C这三类资源 */
	public int A;
	public int B;
	public int C;

	public Sources() {
	}
	
	public Sources(int A,int B,int C) {
		this.A = A;
		this.B = B;
		this.C = C;
	}
	
	public String toString()
	{
		//打印出资源信息
		return A+" "+B+" "+C;
	}
}

  • 0
    点赞
  • 1
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

简介 笔者当初为了学习JAVA,收集了很多经典源码,源码难易程度分为初级、中级、高级等,详情看源码列表,需要的可以直接下载! 这些源码反映了那时那景笔者对未来的盲目,对代码的热情、执着,对IT的憧憬、向往!此时此景,笔者只专注Android、Iphone等移动平台开发,看着这些源码心中有万分感慨,写此文章纪念那时那景! Java 源码包 Applet钢琴模拟程序java源码 2个目标文件,提供基本的音乐编辑功能。编辑音乐软件的朋友,这款实例会对你有所帮助。 Calendar万年历 1个目标文件 EJB 模拟银行ATM流程及操作源代码 6个目标文件,EJB来模拟银行ATM机的流程及操作:获取系统属性,初始化JNDI,取得Home对象的引用,创建EJB对象,并将当前的计数器初始化,调用每一个EJB对象的count()方法,保证Bean正常被激活和钝化,EJB对象是用完毕,从内存中清除,从账户中取出amt,如果amt>账户余额抛出异常,一个实体Bean可以表示不同的数据实例,我们应该通过主键来判断删除哪个数据实例…… ejbCreate函数用于初始化一个EJB实例 5个目标文件,演示Address EJB的实现 ,创建一个EJB测试客户端,得到名字上下文,查询jndi名,通过强制转型得到Home接口,getInitialContext()函数返回一个经过初始化的上下文,用client的getHome()函数调用Home接口函数得到远程接口的引用,用远程接口的引用访问EJB。 EJB中JNDI的使用源码例子 1个目标文件,JNDI的使用例子,有源代码,可以下载参考,JNDI的使用,初始化Context,它是连接JNDI树的起始点,查找你要的对象,打印找到的对象,关闭Context…… ftp文件传输 2个目标文件,FTP的目标是:(1)提高文件的共享性(计算机程序和/或数据),(2)鼓励间接地(通过程序)使用远程计算机,(3)保护用户因主机之间的文件存储系统导致的变化,(4)为了可靠和高效地传输,虽然用户可以在终端上直接地使用它,但是它的主要作用是供程序使用的。本规范尝试满足大型主机、微型主机、个人工作站、和TACs 的不同需求。例如,容易实现协议的设计。 Java EJB中有、无状态SessionBean的两个例子 两个例子,无状态SessionBean可会话Bean必须实现SessionBean,获取系统属性,初始化JNDI,取得Home对象的引用,创建EJB对象,计算利息等;在有状态SessionBean中,用累加器,以对话状态存储起来,创建EJB对象,并将当前的计数器初始化,调用每一个EJB对象的count()方法,保证Bean正常被激活和钝化,EJB对象是用完毕,从内存中清除…… Java Socket 聊天通信演示代码 2个目标文件,一个服务器,一个客户端。 Java Telnet客户端实例源码 一个目标文件,演示Socket的使用。 Java 组播组中发送和接受数据实例 3个目标文件。 Java读写文本文件的示例代码 1个目标文件。 java俄罗斯方块 一个目标文件。 Java非对称加密源码实例 1个目标文件 摘要:Java源码,算法相关,非对称加密   Java非对称加密源程序代码实例,本例中使用RSA加密技术,定义加密算法可用 DES,DESede,Blowfish等。   设定字符串为“张三,你好,我是李四”   产生张三的密钥对(keyPairZhang)   张三生成公钥(publicKeyZhang)并发送给李四,这里发送的是公钥的数组字节   通过网络或磁盘等方式,把公钥编码传送给李四,李四接收到张三编码后的公钥,将其解码,李四用张三的公钥加密信息,并发送给李四,张三用自己的私钥解密从李四处收到的信息…… Java利用DES私钥对称加密代码实例 同上 java聊天室 2个目标文件,简单。 java模拟掷骰子2个 1个目标文件,输出演示。 java凭图游戏 一个目标文件,简单。 java求一个整数的因子 如题。 Java生成密钥的实例 1个目标文件 摘要:Java源码,算法相关,密钥   Java生成密钥、保存密钥的实例源码,通过本源码可以了解到Java如何产生单钥加密的密钥(myKey)、产生双钥的密钥对(keyPair)、如何保存公钥的字节数组、保存私钥到文件privateKey.dat、如何用Java对象序列化保存私钥,通常应对私钥加密后再保存、如何从文件中得到公钥编码的字节数组、如何从字节数组解码公钥。 Java数据压缩与传输实例 1个目标文件 摘要:Java源码,文件操作,数据压缩,文件传输   Java数据压缩与传输实例,可以学习一下实例化套按字、得到文件输入流、压缩输入流、文件输出流、实例化缓冲
©️2021 CSDN 皮肤主题: 1024 设计师:白松林 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值