`
xurichusheng
  • 浏览: 336255 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

【转】 模拟银行业务调度系统

阅读更多

 

转自:CSDN,itm_hadf 的博客 : http://blog.csdn.net/itm_hadf/article/details/7599814

 

注:由于这个程序比较好,所以保存了下来。

 

【一】需求:



模拟实现银行业务调度系统逻辑,具体需求如下:

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

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

    异步随机生成各种类型的客户,生成各类型用户的概率比例为:

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

    客户办理业务所需时间有最大值和最小值,在该范围内随机设定每个VIP客户以及普通客户办理业务所需的时间,快速客户办理业务所需时间为最小值(提示:办理业务的过程可通过线程Sleep的方式模拟)。

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

    当VIP(6号)窗口和快速业务(5号)窗口没有客户等待办理业务的时候,这两个窗口可以处理普通客户的业务,而一旦有对应的客户等待办理业务的时候,则优先处理对应客户的业务。

    随机生成客户时间间隔以及业务办理时间最大值和最小值自定,可以设置。

    不要求实现GUI,只考虑系统逻辑实现,可通过Log方式展现程序运行结果。

 

 

【2】面向对象的分析和设计:

        有三种对应类型的客户:VIP客户,普通客户,快速客户 ,异步随机生成各种类型的客户,各类型客户在其对应窗口按顺序依次办理业务 。
         每一个客户其实就是由银行的一个取号机器产生号码的方式来表示的。所以,我想到要有一个号码管理器对象,让这个对象不断地产生号码,就等于随机生成了客户。

         由于有三类客户,每类客户的号码编排都是完全独立的,所以,我想到本系统一共要产生三个号码管理器对象,各自管理一类用户的排队号码。
        这三个号码管理器对象统一由一个号码机器进行管理,这个号码机器在整个系统中始终只能有一个,所以,它要被设计成单例。

         各类型客户在其对应窗口按顺序依次办理业务 ,准确地说,应该是窗口依次叫号。

         各个窗口怎么知道该叫哪一个号了呢?它一定是问的相应的号码管理器,即服务窗口每次找号码管理器获取当前要被服务的号码。

具体实现:

 

JDK : 1.6.0_20

 

jar : log4j-1.2.8.jar

       commons-lang-2.4.jar

 

常量类 Constants

/**
 * @ClassName: Constants
 * @Description: 常量类
 * @author 
 * @company 
 * @date 2012-6-13
 * @version V1.0
 */

public class Constants {

	/** 此常量用于表示窗口最大的服务时间 : 10秒 */
	public static final int MAX_SERVICE_TIME = 10000;

	/** 此常量用于表示窗口最小的服务时间 : 1秒 */
	public static final int MIN_SERVICE_TIME = 1000;

	/**
	 * 此常量用于表示为【普通客户】服务的---->> : 间隔时间
	 * 
	 * 每个普通窗口服务一个客户的平均时间为5秒,一共有4个这样的窗口,也就是说银行的所有普通窗口合起来
	 * 平均1.25秒内可以服务完一个普通客户,再加上快速窗口和VIP窗口也可以服务普通客户, 
	 * 所以,1秒钟产生一个普通客户比较合理。。。
	 * 
	 */
	public static final int COMMON_CUSTOMER_INTERVAL_TIME = 1;
}
 

枚举类 CustomerType

/**
 * @ClassName: CustomerType
 * @Description: 系统中有三种类型的客户,所以用定义一个枚举类,其中定义三个成员分别表示三种类型的客户。
 * @author 
 * @company
 * @date 2012-6-13
 * @version V1.0
 */

public enum CustomerType {

	COMMON, EXPRESS, VIP;

	public String toString() {

		switch (this) {
		case COMMON:
			return "普通客户";
		case EXPRESS:
			return "快速客户";
		case VIP:
			return name();
		}
		return null;
	};
}

 

号码管理器 NumberManager

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;

import org.apache.log4j.Logger;

/**
 * @ClassName: NumberManager
 * @Description: 号码管理器.此类用来生成三种 不同类型的号码,以及 对该号码的取得。
 * @author 
 * @company
 * @date 2012-6-13
 * @version V1.0
 */

public class NumberManager {

	private static Logger log = Logger.getLogger(NumberManager.class);

	/** 等待服务队列中的 最后一个号码 */
	private int lastNumber = 1;

	/** 一个等待服务的队列 */
	private BlockingQueue<Integer> queue = new LinkedBlockingQueue<Integer>();

	/**
	 * @Title: generateNewManager
	 * @Description: 产生 一个新的号码
	 * @return:Integer
	 * @author 
	 * @date 2012-6-13
	 */
	public Integer generateNewManager() {
		// 将指定元素插入此队列中
		queue.add(lastNumber);

		return lastNumber++;
	}

	/**
	 * @Title: fetchServiceNumber
	 * @Description: 取得一个服务的号码
	 * @return:Integer
	 * @author 
	 * @date 2012-6-13
	 */
	public Integer fetchServiceNumber() {

		Integer number = null;

		if (0 < queue.size()) {

			try {
				/*
				 * 取出BlockingQueue里排在首位的对象,若不能立即取出,则可以等100微妙,
				 * 取不到时返回null
				 */
				number = queue.poll(100, TimeUnit.MICROSECONDS);

			} catch (InterruptedException e) {
				log.error("get the first value of BlockingQueue fail!", e);
			} catch (Exception e) {
				log.error("get the first value of BlockingQueue fail!", e);
			}
		}
		return number;
	}
}
 

号码机器(取号机) NumberMachine

/**
 * @ClassName: NumberMachine
 * @Description: 号码机器(取号机)
 * @author 
 * @company
 * @date 2012-6-13
 * @version V1.0
 */

public class NumberMachine {

	//银行取号机只有一个,故将其设计为单例
	private static final NumberMachine instance = new NumberMachine();
	
	private NumberMachine(){}
	
	public static NumberMachine getInstance() {
		return instance;
	}
	
	/** 普通窗口号码管理器 */
	private NumberManager commonManager = new NumberManager();
	
	/** 快速窗口号码管理器 */
	private NumberManager expressManager = new NumberManager();
	
	/** vip窗口号码管理器  */
	private NumberManager vipManager = new NumberManager();
	

	/**
	 * @return the commonManager(普通窗口号码管理器)
	 */
	public NumberManager getCommonManager() {
		return commonManager;
	}

	/**
	 * @return the expressManager(快速窗口号码管理器)
	 */
	public NumberManager getExpressManager() {
		return expressManager;
	}

	/**
	 * @return the vipManager(vip窗口号码管理器)
	 */
	public NumberManager getVipManager() {
		return vipManager;
	}
}
 

服务窗口 ServiceWindow

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

import org.apache.commons.lang.time.StopWatch;
import org.apache.log4j.Logger;

/**
 * @ClassName: ServiceWindow
 * @Description: 服务窗口(普通窗口,快速窗口,vip窗口)
 * @author 
 * @company 
 * @date 2012-6-13
 * @version V1.0
 */

public class ServiceWindow {

	private static Logger log = Logger.getLogger(ServiceWindow.class);

	/** 客户类型:普通客户 */
	private CustomerType type = CustomerType.COMMON;

	// 服务窗口所显示的号码
	private int windowId = 1;

	/**
	 * @Title: start
	 * @Description: 内部启动一个线程,根据服务窗口的类别分别循环调用三个不同的方法
	 * @author 
	 * @date 2012-6-13
	 */
	public void start() {

		/** 使用线程池运行 */
		Executors.newSingleThreadExecutor().execute(new Runnable() {

			@Override
			public void run() {

				while (true) {

					switch (type) {
					case COMMON:
						commonService();
						break;
					case EXPRESS:
						expressService();
						break;
					case VIP:
						vipService();
						break;
					}
				}
			}

		});
	}

	/**
	 * @Title: commonService
	 * @Description: 普通客户服务
	 * @author 
	 * @date 2012-6-13
	 */
	private void commonService() {

		String windowName = "第" + windowId + "号" + type + "窗口";

		// 取得一个服务的号码
		Integer serviceNumber = NumberMachine.getInstance().getCommonManager()
				.fetchServiceNumber();

		System.out.println(windowName + "开始获取普通任务!");

		if (null != serviceNumber) {

			System.out.println(windowName + "为第" + serviceNumber + "个普通"
					+ "客户服务");

			StopWatch sWatch = new StopWatch();
			sWatch.start();

			int maxRandom = Constants.MAX_SERVICE_TIME
					- Constants.MIN_SERVICE_TIME;
			// 服务时间
			long serviceTime = new Random().nextInt(maxRandom) + 1
					+ Constants.MIN_SERVICE_TIME;

			try {
				Thread.sleep(serviceTime);
			} catch (InterruptedException e) {
				log.error("Thread sleep InterruptedException", e);
			}

			sWatch.stop();

			System.out.println(windowName + "为第" + serviceNumber + "个" + type
					+ "客户完成服务,耗时:" + sWatch.toString());
		} else {
			System.out.println(windowName + "没有取到任务 ,先休息一秒钟。。。");
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				log.error("Thread sleep InterruptedException", e);
			}
		}
	}

	/**
	 * @Title: expressService
	 * @Description: 快速客户服务
	 * @author 
	 * @date 2012-6-13
	 */
	private void expressService() {

		String windowName = "第" + windowId + "号" + type + "窗口";
		// 取得一个服务的号码
		Integer serviceNumber = NumberMachine.getInstance().getExpressManager()
				.fetchServiceNumber();

		System.out.println(windowName + "开始获取快速任务!");

		if (null != serviceNumber) {

			System.out.println(windowName + "为第" + serviceNumber + "个" + type
					+ "客户服务");

			StopWatch sWatch = new StopWatch();
			sWatch.start();

			int serviceTime = Constants.MIN_SERVICE_TIME;
			try {
				/**
				 * 要求 :办理业务的过程----->> : 可以用通过 Sleep 的方式 模拟。
				 * 
				 */
				Thread.sleep(serviceTime);
			} catch (InterruptedException e) {
				log.error("Thread sleep InterruptedException", e);
			}

			sWatch.stop();

			System.out.println(windowName + "为第" + serviceNumber + "个" + type
					+ "客户完成服务,耗时:" + sWatch.toString());
		} else {
			System.out.println(windowName + "没有取到快速任务!");
			/**
			 * 要求 :当 VIP【6】号窗口 和 快速业务【5】号窗口没有客户等待办理业务的时候, 这两个窗口可以处理普通客户的业务。
			 * 而一旦,有对应的客户等待办理业务的时候,则优先处理对应客户的业务。
			 */
			commonService();
		}
	}

	/**
	 * @Title: vipService
	 * @Description: vip客户服务
	 * @author 
	 * @date 2012-6-13
	 */
	private void vipService() {

		String windowName = "第" + windowId + "号" + type + "窗口";
		// 取得一个服务的号码
		Integer serviceNumber = NumberMachine.getInstance().getVipManager()
				.fetchServiceNumber();

		System.out.println(windowName + "开始获取VIP任务!");

		if (null != serviceNumber) {

			System.out.println(windowName + "为第" + serviceNumber + "个" + type
					+ "客户服务");

			StopWatch watch = new StopWatch();
			watch.start();

			int maxRandom = Constants.MAX_SERVICE_TIME
					- Constants.MIN_SERVICE_TIME;
			long serviceTime = new Random().nextInt(maxRandom) + 1
					+ Constants.MIN_SERVICE_TIME;

			try {
				Thread.sleep(serviceTime);
			} catch (InterruptedException e) {
				log.error("Thread sleep InterruptedException", e);
			}

			System.out.println(windowName + "为第" + serviceNumber + "个" + type
					+ "客户服务完成,耗时:" + watch.toString());
		} else {
			System.out.println(windowName + "没有取到VIP任务!");
			commonService();
		}

	}

	/**
	 * @param type
	 *            the type to set
	 */
	public void setType(CustomerType type) {
		this.type = type;
	}

	/**
	 * @param windowId
	 *            the windowId to set
	 */
	public void setWindowId(int windowId) {
		this.windowId = windowId;
	}
}

 

测试 Client

public class Client {

	/**
	 * @Title: main
	 * @Description: TODO
	 * @param args
	 *            :
	 * @author 
	 * @date 2012-6-13
	 */
	public static void main(String[] args) {

		/**
		 * 用for循环创建出4个普通窗口,再创建出1个快速窗口和一个VIP窗口。 
    	 * 接着再创建三个定时器,分别定时去创建新的普通客户号码、新的快速客户号码、新的VIP客户号码
		 */
		for (int i = 0; i < 5; i++) {
			ServiceWindow commonWindow = new ServiceWindow();
			commonWindow.setWindowId(i);
			commonWindow.start();
		}

		ServiceWindow expressWindow = new ServiceWindow();
		expressWindow.setType(CustomerType.EXPRESS);
		expressWindow.start();

		ServiceWindow vipWindow = new ServiceWindow();
		vipWindow.setType(CustomerType.VIP);
		vipWindow.start();
		
		/**
		 * 创建一个线程池,它可安排在给定延迟后运行命令或者定期地执行.
		 * 初始化有1个线程
		 */
		Executors.newScheduledThreadPool(1).scheduleAtFixedRate(new Runnable() {
			@Override
			public void run() {
				Integer number = NumberMachine.getInstance().getCommonManager()
						.generateNewManager();
				System.out.println(number + "号普通客户正在等待服务。。。");
			}
		}, 0, Constants.COMMON_CUSTOMER_INTERVAL_TIME, TimeUnit.SECONDS);

		Executors.newScheduledThreadPool(1).scheduleAtFixedRate(new Runnable() {
			@Override
			public void run() {
				Integer number = NumberMachine.getInstance()
						.getExpressManager().generateNewManager();
				System.out.println(number + "号快速客户正在等待服务。。。");
			}
		}, 0, Constants.COMMON_CUSTOMER_INTERVAL_TIME * 6, TimeUnit.SECONDS);

		Executors.newScheduledThreadPool(1).scheduleAtFixedRate(new Runnable() {
			@Override
			public void run() {
				Integer number = NumberMachine.getInstance().getVipManager()
						.generateNewManager();
				System.out.println(number + "号VIP客户正在等待服务。。。");
			}
		}, 0, Constants.COMMON_CUSTOMER_INTERVAL_TIME * 2, TimeUnit.SECONDS);
	}

}
 

测试结果:

第0号普通客户窗口开始获取普通任务!
第0号普通客户窗口没有取到任务 ,先休息一秒钟。。。
第1号VIP窗口开始获取VIP任务!
第1号VIP窗口没有取到VIP任务!
第1号VIP窗口开始获取普通任务!
第1号VIP窗口没有取到任务 ,先休息一秒钟。。。
第4号普通客户窗口开始获取普通任务!
第4号普通客户窗口没有取到任务 ,先休息一秒钟。。。
第2号普通客户窗口开始获取普通任务!
第2号普通客户窗口没有取到任务 ,先休息一秒钟。。。
1号快速客户正在等待服务。。。
1号VIP客户正在等待服务。。。
1号普通客户正在等待服务。。。
第1号快速客户窗口开始获取快速任务!
第1号快速客户窗口没有取到快速任务!
第1号普通客户窗口开始获取普通任务!
第1号普通客户窗口没有取到任务 ,先休息一秒钟。。。
第1号快速客户窗口开始获取普通任务!
第1号快速客户窗口为第1个普通客户服务
第3号普通客户窗口开始获取普通任务!
第3号普通客户窗口没有取到任务 ,先休息一秒钟。。。
第0号普通客户窗口开始获取普通任务!
第4号普通客户窗口开始获取普通任务!
第4号普通客户窗口没有取到任务 ,先休息一秒钟。。。
第1号VIP窗口开始获取VIP任务!
第0号普通客户窗口没有取到任务 ,先休息一秒钟。。。
第1号VIP窗口为第1个VIP客户服务
2号普通客户正在等待服务。。。
第2号普通客户窗口开始获取普通任务!
第2号普通客户窗口为第2个普通客户服务
第1号普通客户窗口开始获取普通任务!
第1号普通客户窗口没有取到任务 ,先休息一秒钟。。。
第3号普通客户窗口开始获取普通任务!
第3号普通客户窗口没有取到任务 ,先休息一秒钟。。。
第0号普通客户窗口开始获取普通任务!
第4号普通客户窗口开始获取普通任务!
第4号普通客户窗口没有取到任务 ,先休息一秒钟。。。
第0号普通客户窗口没有取到任务 ,先休息一秒钟。。。
3号普通客户正在等待服务。。。
2号VIP客户正在等待服务。。。
第1号普通客户窗口开始获取普通任务!
第1号普通客户窗口为第3个普通客户服务
第3号普通客户窗口开始获取普通任务!
第3号普通客户窗口没有取到任务 ,先休息一秒钟。。。
第4号普通客户窗口开始获取普通任务!
第0号普通客户窗口开始获取普通任务!
第0号普通客户窗口没有取到任务 ,先休息一秒钟。。。
第4号普通客户窗口没有取到任务 ,先休息一秒钟。。。
4号普通客户正在等待服务。。。
第3号普通客户窗口开始获取普通任务!
第3号普通客户窗口为第4个普通客户服务
第0号普通客户窗口开始获取普通任务!
第0号普通客户窗口没有取到任务 ,先休息一秒钟。。。
第4号普通客户窗口开始获取普通任务!
第4号普通客户窗口没有取到任务 ,先休息一秒钟。。。
5号普通客户正在等待服务。。。
3号VIP客户正在等待服务。。。
第0号普通客户窗口开始获取普通任务!
第0号普通客户窗口为第5个普通客户服务
第4号普通客户窗口开始获取普通任务!
第4号普通客户窗口没有取到任务 ,先休息一秒钟。。。
6号普通客户正在等待服务。。。
第2号普通客户窗口为第2个普通客户客户完成服务,耗时:0:00:04.553
第2号普通客户窗口开始获取普通任务!
第2号普通客户窗口为第6个普通客户服务
第4号普通客户窗口开始获取普通任务!
第4号普通客户窗口没有取到任务 ,先休息一秒钟。。。
7号普通客户正在等待服务。。。
2号快速客户正在等待服务。。。
4号VIP客户正在等待服务。。。
第4号普通客户窗口开始获取普通任务!
第4号普通客户窗口为第7个普通客户服务
8号普通客户正在等待服务。。。

 

分享到:
评论

相关推荐

    银行业务调度系统模拟

    银行业务调度系统模拟,是自己看视频一边学习一边编写的,经过分析,没有问题。

    模拟银行调度系统

    基于Java面向对象的封装、多线程、单例设计模式、集合模拟实现银行业务调度系统逻辑。(包括银行调度系统的项目介绍文档、分析以及整个项目工程)

    银行业务调度管理系统

    银行业务调度管理系统,模拟实现银行的业务排队调度功能

    银行业务调度系统优化版(多线程)

    模拟实现银行业务调度系统逻辑,具体需求如下: 银行内有6个业务窗口,1 - 4号窗口为普通窗口,5号窗口为快速窗口,6号窗口为VIP窗口。 有三种对应类型的客户:VIP客户,普通客户,快速客户(办理如交水电费、电话...

    java开发的银行调度系统

    模拟实现银行业务调度系统逻辑,具体需求如下: 银行内有6个业务窗口,1 - 4号窗口为普通窗口,5号窗口为快速窗口,6号窗口为VIP窗口。 有三种对应类型的客户:VIP客户,普通客户,快速客户(办理如交水电费、电话...

    张孝祥 7k面试题 银行业务调度系统改进

    四、服务窗口不用每隔1秒检查,服务完后就检查是否有客户等待服务,而且最好不打印“没取得任务,空闲一秒”,因为作为模拟场景的输出,这样的阅读性不是很好。 五、客户取得号码的时候显示前面有几人在排队字样,...

    银行业务调度视频教学

    完整的项目视频教学,可以实现后台银行业务调度模拟实现

    银行调度系统

    java模拟实现银行业务调度系统逻辑,有三种对应类型的客户:VIP客户,普通客户,快速客户(办理如交水电费、电话费之类业务的客户),异步随机生成各种类型的客户,生成各类型用户的概率比例为:VIP客户 :普通客户 ...

    Java多线程实现银行排队叫号管理系统(GUI实现)

    模拟实现银行业务调度系统逻辑,具体需求如下: • 银行内有6个业务窗口,1 - 4号窗口为普通窗口,5号窗口为快速窗口,6号窗口为VIP窗口。 • 有三种对应类型的客户:VIP客户,普通客户,快速客户(办理如交水...

    黑马程序员--银行管理系统

    模拟实现银行业务调度系统逻辑,具体需求如下: 1.银行内有6个业务窗口,1 - 4号窗口为普通窗口,5号窗口为快速窗口,6号窗口为VIP窗口。 2.有三种对应类型的客户:VIP客户,普通客户,快速客户(办理如交水电费、...

    基于JAVA的模拟ATM系统的设计与实现【文献综述】.pdf

    ATM 银行系统正适应了当今社会快 节奏地生活,使顾客可以方便快捷轻松地办理各种实物银行所能办理的各种业务,大大节 约了时间和实物银行所需的人力,物力,财力等[1]。 一、ATM 系统 模拟 ATM 系统就是对提款机操作...

    Code for bank queue.7z

    模拟实现银行业务调度系统逻辑,具体需求如下: • 银行内有6个业务窗口 • 有三种对应类型的客户 • 异步随机生成各种类型的客户.

    Java高级程序设计-多线程(二).pptx

    3.1 线程安全 多线程编程时,由于系统对线程的调度具有一定的随机性,所以,使用多个线程操作同一个数据时,容易出现线程安全问题。 当多个线程访问同一个资源时,如果控制不好,也会造成数据的不正确性。 以银行取...

    Java范例开发大全 (源程序)

     实例214 模拟操作系统的进程调度 379  实例215 利用栈将字符串逆序输出 381  实例216 动态的数组链表 382  实例217 你能猜出鱼是谁的宠物吗? 387  实例218 使用Collections类对List的排序操作 393  ...

    java范例开发大全(pdf&源码)

    实例214 模拟操作系统的进程调度 379 实例215 利用栈将字符串逆序输出 381 实例216 动态的数组链表 382 实例217 你能猜出鱼是谁的宠物吗? 387 实例218 使用Collections类对List的排序操作 393 实例219 LinkedList的...

    java范例开发大全源代码

     实例172 银行自动存取一体机 278  9.4 多态 284  实例173 饮食文化 284  实例174 使用构造方法的重载计算课程的GPA值 287  第10章 内部类与接口(教学视频:41分钟) 290  10.1 成员内部类 290 ...

    java范例开发大全

    实例214 模拟操作系统的进程调度 379 实例215 利用栈将字符串逆序输出 381 实例216 动态的数组链表 382 实例217 你能猜出鱼是谁的宠物吗? 387 实例218 使用Collections类对List的排序操作 393 实例219 LinkedList的...

Global site tag (gtag.js) - Google Analytics