——银行业务调度系统

本文介绍了一个银行业务调度系统的详细设计。系统包含6个业务窗口,支持VIP、快速和普通客户的不同需求。通过异步随机生成各类客户并合理分配至相应窗口,确保高效有序的服务流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

---------------------- <a href="http://www.itheima.com"target="blank">ASP.Net+Unity开发</a>、<a href="http://www.itheima.com"target="blank">.Net培训</a>、期待与您交流! ----------------------

银行业务调度系统

需求:

   1,银行内有6个业务窗口,1-4号窗口为普通窗口,5号窗口为快速窗口,

6号窗口为VIP窗口。

   2,有三种对应类型的客户:VIP,普通客户,快速客户(办理如交水电费,话费之类的业务的客户)。

   3,异步随机生成各种业务类型的客户,生成各类型的客户的比例为:

VIP客户:快速客户:普通客户 = 1:3:6。

   4,客户办理业务所需时间有最大值和最小值,在该范围内随机设定每个VIP客户

以及普通客户办理业务所需的时间,快速客户办理业务所需的时间为最小值。

   5,各类型客户在器对应窗口按顺序依次办理业务。

   6,当VIP(6号)窗口和快速业务(5号)窗口没有客户等待办理业务的时候,

这两个窗口可以处理普通客户的业务,而一旦有对应的客户等待办理业务时,则优先处理对应客户的业务。

   7,随机生成客户的时间间隔及业务办理时间的最大值和最小值自定。


分析:

1,客户:要去银行办理业务的人。

2,取号:去银行办理业务的时候,都会取票排队,所以有一个取票器。

3,出票:而不同的客户办理的业务也是不同的,按需求分出了三类客户,那么就有三个产生不同类型票号的票号管理器。

4,办理业务:顾客取到号排队后,交道号之后就要去办理业务,所以要有办理业务的窗口。

客户:

1,因为客户要办理的业务是不同的,但客户的类型是固定的,所以要有一个用于描述客户的类。

        取号:

1,客户来了之后就要取票办理业务,所以取票器要有产生客户号的方法;

2,而客户的数量是不固定的,所以取票器要有一个集合来存储客户。

3,当一个顾客办理完业务之后,就要把后面的客户的排队顺序向前移一位,所以要有一个移出办理业务结束的客户的方法。

出票:

1,因为业务的不同,所以取票器中,要有三个不同的票号管理器;

办理业务:

1,窗口会定时的叫号,对应业务的客户被叫到号后就会到对应的窗口办理业务,这就要问出票器有没有对应的票号;

2,窗口办理完业务之后,就会要叫下一个号,如果快速窗口和VIP窗口没有客户,则就去办理普通业务。

对应类的示例代码:

票号管理器类:

 为客户生产对应类型业务的票号,当客户办理完业务时,取出对应的票号。

package com.itheima.bank;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 票号管理器
 * @author wuyong
 *
 */
public class NOManager {
	//票号
	private Integer lastNO = 1;
	private List queueNos = new ArrayList();
	/**
	 * 创建票号
	 * @return
	 */
	public synchronized Integer generateNewNO(){
		queueNos.add(lastNO);
		return lastNO ++;
	}
	
	/**
	 * 获得当前服务的号码
	 * @return
	 */
	public synchronized Integer fetchServiceNO(){
		if (queueNos.size() > 0) 
			return queueNos.remove(0);
		return null;
	}
}

取票器类:

因为,每一个客户到银行取号,都是到取票器取号的,所以取票器用单例设计。

package com.itheima.bank;

/**
 * 出票器。
 * @author wuyong
 *
 */
public class NOMachine {
	//普通的票号管理器
	private NOManager commonManager = new NOManager();
	//快速的票号管理器
	private NOManager expressManager = new NOManager();
	//VIP的票号管理器
	private NOManager vipManager = new NOManager();
	
	public NOManager getCommonManager() {
		return commonManager;
	}

	public NOManager getExpressManager() {
		return expressManager;
	}

	public NOManager getVipManager() {
		return vipManager;
	}
	/**
	 * 单例模式
	 */
	private static final NOMachine instance = new NOMachine();
	private NOMachine(){}
	public static NOMachine getInsatnce(){
		return instance;
	}
}

服务窗口类:

  生产4个普通窗口,1个快速窗口,1个VIP窗口,办理三种类型的业务。

package com.itheima.bank;

import java.util.Random;
import java.util.concurrent.Executors;

/**
 * 窗口
 * @author wuyong
 *
 */
public class ServiceWindow {
	//用户的类型
	private CustomerType type = CustomerType.COMMON;
	//窗口编号
	private int windowId = 1;
	public void setType(CustomerType type) {
		this.type = type;
	}
	public void setWindowId(int windowId) {
		this.windowId = windowId;
	}
	//取票器
	private NOMachine noMachine = NOMachine.getInsatnce();
	
	public void start(){
		Executors.newSingleThreadExecutor().execute(
				new Runnable() {
					public void run() {
						while (true) {
							switch (type) {
							case COMMON:
								commonService();
								break;
							case EXPRESS:
								expressService();
								break;
							case VIP:
								vipService();
								break;
							}
						}
					}
				}
		);
	}

	private void commonService() {
		Integer no = noMachine.getCommonManager().fetchServiceNO();
		String windowName = "第" + windowId + "号" + type +"窗口";
		System.out.println(windowName + "正在获取任务");
		if (no != null) {
			System.out.println(windowName + "开始为第" + no + "个普通客户服务");
			long startTime = System.currentTimeMillis();
			int maxServiceTime = Constants.MAX_SERVICE_TIME - Constants.MIN_SERVICE_TIME;
			int serviceTime = new Random().nextInt(maxServiceTime) + Constants.MIN_SERVICE_TIME;
			try {
				Thread.sleep(serviceTime);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			int usedTime = (int)(System.currentTimeMillis() - startTime) / 1000;
			System.out.println(windowName + "为第" + no + "个普通客户完成了业务,耗时:" + usedTime + "秒");
		}
		else {
			System.out.println(windowName + "没有获得任务!空闲一秒钟!");
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
	

	private void expressService() {
		Integer no = noMachine.getExpressManager().fetchServiceNO();
		String windowName = "第" + windowId + "号" + type +"窗口";
		System.out.println(windowName + "正在获取任务");
		if (no != null) {
			System.out.println(windowName + "开始为第" + no + "个快速客户服务");
			long startTime = System.currentTimeMillis();
			long serviceTime = Constants.MIN_SERVICE_TIME;
			try {
				Thread.sleep(serviceTime);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			int usedTime = (int)(System.currentTimeMillis() - startTime) / 1000;
			System.out.println(windowName + "为第" + no + "个快速客户完成了业务,耗时:" + usedTime + "秒");
		}
		else {
			System.out.println(windowName + "没有获得任务!");
			commonService();
		}
	}

	private void vipService() {
		String windowName = "第" + windowId + "号" + type +"窗口";
		Integer no = noMachine.getVipManager().fetchServiceNO();
		System.out.println(windowName + "正在获取任务");
		if (no != null) {
			System.out.println(windowName + "开始为第" + no + "个VIP客户服务");
			long startTime = System.currentTimeMillis();
			int maxServiceTime = Constants.MAX_SERVICE_TIME - Constants.MIN_SERVICE_TIME;
			int serviceTime = new Random().nextInt(maxServiceTime) + Constants.MIN_SERVICE_TIME;
			try {
				Thread.sleep(serviceTime);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			int usedTime = (int)(System.currentTimeMillis() - startTime) / 1000;
			System.out.println(windowName + "为第" + no + "个VIP客户完成了业务,耗时:" + usedTime + "秒");
		}
		else {
			System.out.println(windowName + "没有获得任务!");
			commonService();
		}
	}
}

客户类型枚举:
用于表示客户的类型,以及其办理业务锁对应的窗口
package com.itheima.bank;

/**
 * 客户类型
 * 类型为枚举
 * @author wuyong
 *
 */
public enum CustomerType {
	COMMON,EXPRESS,VIP;
	//获取对应类型的名称
	public String toString(){
		switch(this){
			case COMMON:
				return "普通";
			case EXPRESS:
				return "快速";
			case VIP:
				return name();
		}
		return null;
	}
}

服务用时类:
设定服务时间的最大值和最小值
package com.itheima.bank;

/**
 * 服务时间的相关信息
 * @author wuyong
 *
 */
public class Constants {
	//服务的最大时间
	public static int  MAX_SERVICE_TIME = 10 * 1000;
	//服务的最小时间
	public static int MIN_SERVICE_TIME = 1 * 1000;
	//普通客户出现的时间
	public static int COMMON_SREVICE_TIME = 1;
}

主函数类:
 模拟银行办理业务
package com.itheima.bank;

import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
 * 主线程类
 * @author wuyong
 *
 */
public class MainClass {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		//1~4号普通窗口
		for (int i = 1; i < 5; i++) {
			ServiceWindow commonWindow = new ServiceWindow();
			commonWindow.setWindowId(i);
			commonWindow.start();
		}
		//快速窗口
		ServiceWindow expressWindow = new ServiceWindow();
		expressWindow.setType(CustomerType.EXPRESS);
		expressWindow.start();
		
		//VIP窗口
		ServiceWindow vipWindow = new ServiceWindow();
		vipWindow.setType(CustomerType.VIP);
		vipWindow.start();
		
		//定时生产一个普通客户,等待服务
		Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
				new Runnable() {
					@Override
					public void run() {
						Integer no = NOMachine.getInsatnce().getCommonManager().generateNewNO();
						System.out.println(no + "号普通客户等待服务。。。");
					}
				}, 
				0, 
				Constants.COMMON_SREVICE_TIME, 
				TimeUnit.SECONDS);
		
		//定时生产一个VIP客户,等待服务
		Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
				new Runnable() {
					@Override
					public void run() {
						Integer no = NOMachine.getInsatnce().getVipManager().generateNewNO();
						System.out.println(no + "号VIP客户等待服务。。。");
					}
				}, 
				0, 
				Constants.COMMON_SREVICE_TIME * 6, 
				TimeUnit.SECONDS);
		
		//定时生产一个快速客户,等待服务
		Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
				new Runnable() {
					@Override
					public void run() {
						Integer no = NOMachine.getInsatnce().getExpressManager().generateNewNO();
						System.out.println(no + "号快速客户等待服务。。。");
					}
				}, 
				0, 
				Constants.COMMON_SREVICE_TIME * 3, 
				TimeUnit.SECONDS);
	}

}


### 银行业务模拟操作系统的实现方案 银行业务模拟操作系统可以通过多种方式来设计和实现,通常会涉及到多线程管理、资源调度以及并发控制等内容。以下是基于提供的参考资料和其他专业知识构建的一个完整的解决方案。 #### 1. 多道批处理与分时技术的应用 在银行系统的设计中,可以借鉴多道批处理的思想来提高CPU利用率并减少响应时间。通过引入分时机制,多个用户的请求能够被合理分配到不同的时间段内完成。这种设计理念有助于提升用户体验的同时也增强了系统的稳定性[^1]。 #### 2. Java语言下的ATM功能模块化开发 对于具体的功能实现部分,如存款、取款等功能,则可参照Java语言中的面向对象编程原则来进行封装。每一个账户都可以看作是一个独立的对象实例;而诸如存入金额、取出金额这样的动作则定义成相应类里的成员函数。下面给出了一段简单的代码示例用于演示基本框架: ```java public class BankAccount { private double balance; public synchronized void deposit(double amount){ if(amount >0 ){ this.balance +=amount; System.out.println(Thread.currentThread().getName()+" deposited "+amount); } } public synchronized boolean withdraw(double amount)throws InterruptedException{ while(this.balance<amount){ wait(); // If insufficient funds, make thread wait until notified. } if(balance >= amount && amount>0){ Thread.sleep(10); // Simulate transaction delay. this.balance -=amount; notifyAll(); return true; }else{ return false; } } public double getBalance(){ return this.balance; } } ``` 此代码片段展示了如何利用同步关键字`synchronized`防止多个线程同时访问共享数据造成混乱的情况发生,并且加入了等待通知模式解决可能出现的资金不足问题[^2]。 #### 3. 并发控制——信号量的运用 当考虑到更复杂的场景比如转账服务时,就需要考虑两个不同账户之间的协调工作了。此时就可以采用信号量(Semaphore)的概念配合PV原语(P代表申请资源,V表示释放资源),从而有效避免死锁现象的发生同时也简化了程序结构[^3]。 假设现在有两个账户A,B之间要互相转帐一定数额的钱,在这个过程中我们需要确保整个过程要么完全成功要么彻底失败(即保持一致性)。这里提供了一个伪代码版本的例子说明这一流程: ```pseudo semaphore mutex = 1 // Initialize semaphore with value 1. P(mutex): // Enter critical section. if A's balance >= transfer_amount then do following steps else abort operation. decrease A’s balance by 'transfer_amount'. increase B’s balance by 'transfer_amount'. end-if V(mutex): // Leave critical section after completing task safely. ``` 以上就是有关于创建一个基础版银行业的业务模拟操作系统的一些思路和技术要点介绍。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值