Java基础-银行业务调度系统

 

银行业务调度系统

项目需求:

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

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

3、 异步随机生成各种类型的客户,生成各类型用户的概率比例为:VIP客户 :普通客户 :快速客户  =  1 :6 :3。

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

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

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

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

项目分析与设计:

1、 有三种对应类型的客户:VIP客户,普通客户,快速客户 ,异步随机生成各种类型的客户,各类型客户在其对应窗口按顺序依次办理业务 。

每一个客户其实就是由银行的一个取号机器产生号码的方式来表示的。所以,可以用一 个号码管理器对象,让这个对象不断地产生号码,就等于随机生成了客户。由于有三类 客户,每类客户的号码编排都是完全独立的,所以要产生三个号码管理器对象,各自管 理一类用户的排队号码。这三个号码管理器对象统一由一个号码机器进行管理,这个号 码机器在整个系统中始终只能有一个,所以,它要被设计成单例。

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

服务窗口每次找对应的号码管理器获取当前要被服务的号码。

代码实现

NumberManager类

定义一个用于存储上一个客户号码的成员变量和用于存储所有等待服务的客户号码的队列集合。

定义一个产生新号码的方法和获取马上要为之服务的号码的方法,这两个方法被不同的线程操作了相同的数据,所以,要进行同步

package com.itcast.bank;

import java.util.ArrayList;
import java.util.List;

//创建号码管理器类
public class NumberManager {
	
	//定义变量用于存储产生的号码
	private int lastNumber = 1;
	//定义集合用于存储要服务的号码
	private List<Integer> queueNumber = new ArrayList<Integer>();
	
	//定义方法产生新的号码,并将产生的号码添加到需要服务的队列后
	public synchronized Integer generateNewNumber(){
		queueNumber.add(lastNumber);
		return lastNumber++;
	}

	//定义方法获取要服务的号码
	public synchronized Integer fetchServiceNumber(){
		Integer number = null;
		if(queueNumber.size()>0)
			number = queueNumber.remove(0);
		return number;
	}
}


 

NumberMachine类

定义三个成员变量分别指向三个NumberManager对象,分别表示普通、快速和VIP客户的号码管理器,定义三个对应的方法来返回这三个NumberManager对象。

将NumberMachine类设计成单例。

package com.itcast.bank;

//创建号码生成器类
public class NumberMachine {

	//创建普通,快速,VIP号码管理器
	private NumberManager commonManager = new NumberManager();
	private NumberManager expressManager = new NumberManager();
	private NumberManager vipManager = new NumberManager();
	
	public NumberManager getCommonManager() {
		return commonManager;
	}
	public NumberManager getExpressManager() {
		return expressManager;
	}
	public NumberManager getVipManager() {
		return vipManager;
	}
	
	//将号码生成器实现单例
	private NumberMachine(){}
	private static NumberMachine instance = new NumberMachine();
	public static NumberMachine getInstance(){
		return instance;
	}
}


 

CustomerType枚举类

系统中有三种类型的客户,所以用定义一个枚举类,其中定义三个成员分别表示三种类型的客户。

重写toString方法,返回类型的中文名称。

package com.itcast.bank;

//定义枚举
public enum CustomerType {

	//规定客户和服务窗口的类型
	COMMON,EXPRESS,VIP;
	public String toString(){
		switch(this){
		case COMMON:
			return "普通";
		case EXPRESS:
			return "快速";
		case VIP:
			return name();
		}
		return null;
	}
}


 

Constants类

定义三个常量:

MAX_SERVICE_TIME:最长服务时间、

MIN_SERVICE_TIME:最短服务时间、

COMMON_CUSTOMER_INTERVAL_TIME:产生普通客户的间隔时间

package com.itcast.bank;

//定义常量类,存储用到的常量
public class Constants {

	//最长服务时间
	public static int MAX_SERVICE_TIME = 10000;
	//最短服务时间
	public static int MIN_SERVICE_TIME = 1000;
	//产生普通客户间隔时间
	public static int COMMON_CUSTOMER_INTERVAL_TIME = 1;
}


 

ServiceWindow类

定义一个start方法,内部启动一个线程,根据服务窗口的类别分别循环调用三个不同的方法。 

package com.itcast.bank;

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

//创建服务窗口类
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;
	}
	
	//定义方法,根据服务窗口的类型执行不同的服务
	public void start(){
		//创建单个线程的线程池,并执行服务线程
		Executors.newSingleThreadExecutor().execute(new Runnable(){
			//创建服务线程并实现run方法
			public void run(){
				while(true){
					//根据服务类型的不同执行不同的服务
					switch(type){
					case COMMON:
						commonService();
						break;
					case EXPRESS:
						expressService();
						break;
					case VIP:
						vipService();
						break;
					}
				}
			}

		});
	}
	
	//定义方法,执行普通用户服务
	private void commonService() {
		String windowName = "第" + windowId + "号" + type + "窗口";
		System.out.println(windowName + "正在获取普通任务!");
		//获取要服务的号码
		Integer number = NumberMachine.getInstance().getCommonManager().fetchServiceNumber();
		if(number != null){
			System.out.println(windowName + "正在为" + number +"个普通房客户服务!");
			//定义变量用于存储代码开始执行的时间
			long beginTime = System.currentTimeMillis();
			//限定服务时间在1~10秒之间
			int maxRand = Constants.MAX_SERVICE_TIME - Constants.MIN_SERVICE_TIME;
			long serviceTime = new Random().nextInt(maxRand) + 1 + Constants.MIN_SERVICE_TIME;
			try {
				Thread.sleep(serviceTime);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			//获取代码执行所用的时间
			long castTime = System.currentTimeMillis() - beginTime;
			System.out.println(windowName + "为第" + number +"个普通客户完成服务,耗时" + castTime/1000 +"秒");
		}else{
			System.out.println(windowName + "没有取到任务,先休息1秒钟!");
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
	
	//定义方法,执行快速客户服务
	private void expressService() {
		String windowName = "第" + windowId + "好" + type + "窗口";
		System.out.println(windowName + "正在获取快速任务!");
		Integer num = NumberMachine.getInstance().getExpressManager().fetchServiceNumber();
		if(num != null){
			long beginTime = System.currentTimeMillis();
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			long castTime = System.currentTimeMillis() - beginTime;
			System.out.println(windowName + "为第" + num +"个快速客户完成服务,耗时" + castTime/1000 +"秒");
		}else{
			System.out.println(windowName + "没有取到快速任务!");
			commonService();
		}
	}
	
	//定义方法,执行VIP客户服务
	private void vipService() {
		String windowName = "第" + windowId + "好" + type + "窗口";
		Integer num = NumberMachine.getInstance().getVipManager().fetchServiceNumber();
		System.out.println(windowName + "正在获取VIP任务!");
		if(num != null){
			long beginTime = System.currentTimeMillis();
			int maxRand = Constants.MAX_SERVICE_TIME - Constants.MIN_SERVICE_TIME;
			long serviceTime = new Random().nextInt(maxRand) + 1 + Constants.MIN_SERVICE_TIME;
			try {
				Thread.sleep(serviceTime);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			long castTime = System.currentTimeMillis() - beginTime;
			System.out.println(windowName + "为第" + num +"个VIP客户完成服务,耗时" + castTime +"秒");
		}else{
			System.out.println(windowName + "没有取到VIP任务!");
			commonService();
		}
	}
}


 

MainClass类

用for循环创建出4个普通窗口,再创建出1个快速窗口和一个VIP窗口。

接着再创建三个定时器,分别定时去创建新的普通客户号码、新的快速客户号码、新的VIP客户号码。

package com.itcast.bank;

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

//创建测试类
public class MainClass {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub

		//利用循环,创建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.setWindowId(5);
		expressWindow.start();
		
		//创建VIP客户服务窗口
		ServiceWindow vipWindow = new ServiceWindow();
		vipWindow.setType(CustomerType.VIP);
		vipWindow.setWindowId(6);
		vipWindow.start();
	
		//创建调度线程池,从0开始每隔COMMON_CUSTOMER_INTERVAL_TIME秒产生一个普通用户号码
		Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
				new Runnable(){
					@Override
					public void run() {
						int number = NumberMachine.getInstance().getCommonManager().generateNewNumber();
						System.out.println(number+"号普通客户正在等待服务!");
					}
				}, 
				0, 
				Constants.COMMON_CUSTOMER_INTERVAL_TIME, 
				TimeUnit.SECONDS
			);
		
		//创建调度线程池,从0开始每隔COMMON_CUSTOMER_INTERVAL_TIME*2秒产生一个快速用户号码
		Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
				new Runnable(){
					@Override
					public void run() {
						int number = NumberMachine.getInstance().getExpressManager().generateNewNumber();
						System.out.println(number+"号快速客户正在等待服务!");
					}
				}, 
				0, 
				Constants.COMMON_CUSTOMER_INTERVAL_TIME * 2, 
				TimeUnit.SECONDS
			);
		
		//创建调度线程池,从0开始每隔COMMON_CUSTOMER_INTERVAL_TIME*6秒产生一个VIP用户号码
		Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
				new Runnable(){
					@Override
					public void run() {
						int number = NumberMachine.getInstance().getVipManager().generateNewNumber();
						System.out.println(number+"号VIP客户正在等待服务!");
					}
				}, 
				0, 
				Constants.COMMON_CUSTOMER_INTERVAL_TIME * 6, 
				TimeUnit.SECONDS
			);
	}
}

用到的知识:

1、面向对象设计

2、枚举

3、单例设计模式

4、多线程
运行程序的一部分结果:

第1号普通窗口正在获取普通任务!
第2号普通窗口正在获取普通任务!
第3号普通窗口正在获取普通任务!
第1号普通窗口没有取到任务,先休息1秒钟!
第2号普通窗口没有取到任务,先休息1秒钟!
第3号普通窗口没有取到任务,先休息1秒钟!
第6号VIP窗口正在获取VIP任务!
第6号VIP窗口没有取到VIP任务!
第6号VIP窗口正在获取普通任务!
第5号快速窗口正在获取快速任务!
第4号普通窗口正在获取普通任务!
第6号VIP窗口没有取到任务,先休息1秒钟!
第4号普通窗口没有取到任务,先休息1秒钟!
第5号快速窗口没有取到快速任务!
第5号快速窗口正在获取普通任务!
第5号快速窗口没有取到任务,先休息1秒钟!
1号普通客户正在等待服务!
1号快速客户正在等待服务!
1号VIP客户正在等待服务!
第3号普通窗口正在获取普通任务!
第6号VIP窗口正在获取VIP任务!
第1号普通窗口正在获取普通任务!
第2号普通窗口正在获取普通任务!
第3号普通窗口正在为1个普通房客户服务!
第2号普通窗口没有取到任务,先休息1秒钟!
第1号普通窗口没有取到任务,先休息1秒钟!
第4号普通窗口正在获取普通任务!
第4号普通窗口没有取到任务,先休息1秒钟!
第5号快速窗口正在获取快速任务!
2号普通客户正在等待服务!
第2号普通窗口正在获取普通任务!
第1号普通窗口正在获取普通任务!
第2号普通窗口正在为2个普通房客户服务!
第1号普通窗口没有取到任务,先休息1秒钟!
第5号快速窗口为第1个快速客户完成服务,耗时1秒
第4号普通窗口正在获取普通任务!
第5号快速窗口正在获取快速任务!
第4号普通窗口没有取到任务,先休息1秒钟!
第5号快速窗口没有取到快速任务!
第5号快速窗口正在获取普通任务!
第5号快速窗口没有取到任务,先休息1秒钟!
2号快速客户正在等待服务!
3号普通客户正在等待服务!
第1号普通窗口正在获取普通任务!
第1号普通窗口正在为3个普通房客户服务!
第4号普通窗口正在获取普通任务!
第4号普通窗口没有取到任务,先休息1秒钟!
第5号快速窗口正在获取快速任务!
4号普通客户正在等待服务!
第5号快速窗口为第2个快速客户完成服务,耗时1秒
第4号普通窗口正在获取普通任务!
第4号普通窗口正在为4个普通房客户服务!
第5号快速窗口正在获取快速任务!
第5号快速窗口没有取到快速任务!
第5号快速窗口正在获取普通任务!
第5号快速窗口没有取到任务,先休息1秒钟!
5号普通客户正在等待服务!
3号快速客户正在等待服务!
第3号普通窗口为第1个普通客户完成服务,耗时3秒
第3号普通窗口正在获取普通任务!
第3号普通窗口正在为5个普通房客户服务!
第5号快速窗口正在获取快速任务!
6号普通客户正在等待服务!
第5号快速窗口为第3个快速客户完成服务,耗时1秒
第5号快速窗口正在获取快速任务!
第5号快速窗口没有取到快速任务!
第5号快速窗口正在获取普通任务!
第5号快速窗口正在为6个普通房客户服务!
7号普通客户正在等待服务!
4号快速客户正在等待服务!
2号VIP客户正在等待服务!
第4号普通窗口为第4个普通客户完成服务,耗时2秒
第4号普通窗口正在获取普通任务!
第4号普通窗口正在为7个普通房客户服务!
8号普通客户正在等待服务!
9号普通客户正在等待服务!
5号快速客户正在等待服务!
第2号普通窗口为第2个普通客户完成服务,耗时6秒
第2号普通窗口正在获取普通任务!
第2号普通窗口正在为8个普通房客户服务!
10号普通客户正在等待服务!
第6号VIP窗口为第1个VIP客户完成服务,耗时8秒
第6号VIP窗口正在获取VIP任务!
11号普通客户正在等待服务!
第2号普通窗口为第8个普通客户完成服务,耗时1秒
第2号普通窗口正在获取普通任务!
第2号普通窗口正在为9个普通房客户服务!
6号快速客户正在等待服务!
第4号普通窗口为第7个普通客户完成服务,耗时3秒
第4号普通窗口正在获取普通任务!
第4号普通窗口正在为10个普通房客户服务!
第3号普通窗口为第5个普通客户完成服务,耗时5秒
第3号普通窗口正在获取普通任务!
第3号普通窗口正在为11个普通房客户服务!
12号普通客户正在等待服务!
第1号普通窗口为第3个普通客户完成服务,耗时8秒
第1号普通窗口正在获取普通任务!
第1号普通窗口正在为12个普通房客户服务!
13号普通客户正在等待服务!
7号快速客户正在等待服务!
3号VIP客户正在等待服务!
第4号普通窗口为第10个普通客户完成服务,耗时2秒
第4号普通窗口正在获取普通任务!
第4号普通窗口正在为13个普通房客户服务!
14号普通客户正在等待服务!
第6号VIP窗口为第2个VIP客户完成服务,耗时3秒
第6号VIP窗口正在获取VIP任务!
第3号普通窗口为第11个普通客户完成服务,耗时3秒
第3号普通窗口正在获取普通任务!
第3号普通窗口正在为14个普通房客户服务!
15号普通客户正在等待服务!
8号快速客户正在等待服务!
第5号快速窗口为第6个普通客户完成服务,耗时8秒
第5号快速窗口正在获取快速任务!
16号普通客户正在等待服务!
第1号普通窗口为第12个普通客户完成服务,耗时4秒
第1号普通窗口正在获取普通任务!
第1号普通窗口正在为15个普通房客户服务!
第5号快速窗口为第4个快速客户完成服务,耗时1秒
第5号快速窗口正在获取快速任务!
第4号普通窗口为第13个普通客户完成服务,耗时2秒
第4号普通窗口正在获取普通任务!
第4号普通窗口正在为16个普通房客户服务!
17号普通客户正在等待服务!
9号快速客户正在等待服务!
第2号普通窗口为第9个普通客户完成服务,耗时6秒
第2号普通窗口正在获取普通任务!
第2号普通窗口正在为17个普通房客户服务!
第5号快速窗口为第5个快速客户完成服务,耗时1秒
第5号快速窗口正在获取快速任务!
18号普通客户正在等待服务!
第5号快速窗口为第6个快速客户完成服务,耗时1秒
第5号快速窗口正在获取快速任务!
19号普通客户正在等待服务!
10号快速客户正在等待服务!
4号VIP客户正在等待服务!
第3号普通窗口为第14个普通客户完成服务,耗时4秒
第3号普通窗口正在获取普通任务!
第3号普通窗口正在为18个普通房客户服务!
第5号快速窗口为第7个快速客户完成服务,耗时1秒
第5号快速窗口正在获取快速任务!
20号普通客户正在等待服务!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值