---------------------- ASP.Net+Unity开发、.Net培训、期待与您交流! -----------------------
模拟实现银行业务调度系统的逻辑,具体需求分析如下:
1.银行有6个窗口:1-4号窗口为普通窗口、5号窗口为快速窗口、6号窗口为会员窗口
2.银行分别有三种对应的客户:普通客户、快速客户(办理如交水电费、电话费之类的客户)、会员VIP客户
3.异步随机生成各种类型的客户,生成各类型的客户的比率分别为:普通客户:快速客户:VIP客户=6:3:1
4.客户办理业务所需的时间有最大值和最小值,在该范围内随机设定每个VIP客户和普通客户办理业务所需的时间,快速客户办理业务所需的时间为最小值(提示:办理业务的过程可通过线程的Sleep方式模拟)
5.各类型的客户在其所对应的窗口一次办理业务
6.当VIP(6号)窗口和快速窗口没有客户在等待办理业务的时候,可为普通客户办理业务,而一旦有对应客户等待的时候,则优先处理对应客户的业务。
7.随机生成客户时间间隔以及业务办理时间的最大值和最小值自定,可以设置
8.不要求实现GUI,只要求实现系统逻辑,可通过log的方式展现程序运行的结果
面向对象的分析与设计:
1.由于有三类客户,每类的客户的号码编排都是完全独立的。所以本系统一共要产生三个号码管理器对象,各自管理一类客户的排队号码,这三个号码管理器对象又要统一由一个号码管理器来管理,而这个号码管理器在整个系统中始终只有一个,所以该号码管理器要被设计成单例。
2.各个窗口又怎么知道该叫那一个号了呢?那么它一定是在请求相应的号码管理器,即服务窗口每次找号码管理器对象获取当前要被服务的客户号码。
分析各个类:
NumberManager类
1.定义一个用于存储上一个客户号码的成员变量和用于存储所有等待服务客户号码的的队列结合
2.定义一个产生新号码的方法和获取马上要为之服务的号码的方法,这两个方法被不同的线程操作了相同的数据,所以要进行同步。
NumberMachine类
1.定义三个成员变量分别指向NumberManager对象,分别表示普通、快速、VIP客户的号码管理器,定义三个对应的方法来返回这三个NumberManager对象
2.将NumberMachine设计成单例
CustomerType枚举类
1.系统中有三种类型的客户,所以定义枚举类,其中定义三个成员,分别表示三种类型的客户。
2.重写toString方法,返回类型的中文名称,这是在后面编码时重构出来的,开始不用考虑。
ServiceWindow类
1.定义一个start方法,内部启动一个线程,根据服务窗口的类别分别循环调用三个不同的方法
2.定义三种方法分别对三种客户进行服务,为了观察运行效果,应详细打印出其中的细节信息
MainClass类
1.用for循环创建4个普通窗口,再创建出一个快速窗口和一个VIP窗口
2.再创建三个定时器,分别定时去创建新的普通号码、新的快速客户号码、新的VIP客户号码
Constants类
定义三个常量:MAX_SERVICE_TIME、MIN_SERVICE_TIME、COMMON_CUMSTOMER_INTERVAL_TIME
下面贴出各个模块代码:
NumberManager类:
- package com.itcast.bank;
- import java.util.ArrayList;
- import java.util.List;
- public class NumberManager {
- private int lastNumber=1;//定义上一次返回的号码
- //定义一个泛型的队列结合数组
- private List<Integer> quenueNumber=new ArrayList<Integer>();
- /*
- * synchronized 关键字,代表这个方法加锁,相当于不管哪一个线程(例如线程A),运行到这个方法时
- * 都要检查有没有其它线程B(或者C、 D等)正在用这个方法,有的话要等正在使用synchronized方法的线程B(或者C 、D)
- * 运行完这个方法后再运行此线程A;没有的话,直接运行
- */
- //产生新号码的方法
- public synchronized Integer generateNewManager(){
- quenueNumber.add(lastNumber);//把每次产生的新号码都加入进去
- return lastNumber++;
- }
- //获取服务号的方法
- public synchronized Integer fetchServiceNumber(){
- Integer number=null;
- if(quenueNumber.size()>0){
- number=quenueNumber.remove(0);
- }
- return number;//返回每次被取走的号码
- }
- }
NumberMachine类:
- package com.itcast.bank;
- //返回三个管理器对象
- public class NumberMachine {
- private NumberManager commonManager=new NumberManager();//普通客户
- private NumberManager expressManager=new NumberManager();//快速客户
- private NumberManager vipManager=new NumberManager();//vip客户
- 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枚举类:
- 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;
- }
- }
ServiceWindow类:
- package com.itcast.bank;
- import java.util.Random;
- import java.util.concurrent.Executors;
- public class ServiceWindow {
- private CustomerType type = CustomerType.COMMON;// 定义窗口类型,并设置默认的窗口为普通窗口
- private int windoeId=1;//定义一个顺序号
- public void setType(CustomerType type) {
- this.type = type;
- }
- public void setWindoeId(int windoeId) {
- this.windoeId = windoeId;
- }
- // 定义一个开始方法
- 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;
- }
- }
- }
- //普通服务窗口
- private void commonService() {
- String windowName="第"+windoeId+"号"+type+"窗口";
- System.out.println(windowName+"正在获取普通任务");
- Integer number = NumberMachine.getInstance().getCommonManager().fetchServiceNumber();// 取号
- if(number != null){
- //开始服务,并计时
- System.out.println(windowName+"正在为第"+number+"号普通客户服务");
- long beginTime=System.currentTimeMillis();
- int maxRand=Constans.MAX_SERVICE_TIME-Constans.MIN_SERVICE_TIME;
- long serveTime=new Random().nextInt(maxRand)+1+Constans.MIN_SERVICE_TIME;//服务的时间
- try {
- Thread.sleep(serveTime);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- long costTime=System.currentTimeMillis()-beginTime;
- System.out.println(windowName+"为第"+number+"号普通客户完成服务,花费了"+costTime/1000+"秒");
- }else{
- System.out.println(windowName+"没有取到普通任务,正在空闲1秒!");
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
- //快速服务窗口
- private void expressService() {
- Integer number = NumberMachine.getInstance().getExpressManager().fetchServiceNumber();// 取号
- String windowName="第"+windoeId+"号"+type+"窗口";
- System.out.println(windowName+"正在获取快速任务");
- if(number != null){
- //开始服务,并计时
- System.out.println(windowName+"正在为第"+number+"号快速客户服务");
- long beginTime=System.currentTimeMillis();
- try {
- Thread.sleep(Constans.MIN_SERVICE_TIME);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- long costTime=System.currentTimeMillis()-beginTime;
- System.out.println(windowName+"为第"+number+"号快速客户完成服务,花费了"+costTime/1000+"秒");
- }else{
- System.out.println(windowName+"没有取到快速任务,空闲1秒!");
- commonService();
- }
- }
- //vip服务窗口
- private void vipService() {
- String windowName="第"+windoeId+"号"+type+"窗口";
- Integer number = NumberMachine.getInstance().getVipManager().fetchServiceNumber();// 取号
- System.out.println(windowName+"正在获取VIP任务");
- if(number != null){
- //开始服务,并计时
- System.out.println(windowName+"正在为第"+number+"号VIP客户服务");
- long beginTime=System.currentTimeMillis();
- int maxRand=Constans.MAX_SERVICE_TIME-Constans.MIN_SERVICE_TIME;
- long serveTime=new Random().nextInt(maxRand)+1+Constans.MIN_SERVICE_TIME;//服务的时间
- try {
- Thread.sleep(serveTime);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- long costTime=System.currentTimeMillis()-beginTime;
- System.out.println(windowName+"为第"+number+"号VIP客户完成服务,花费了"+costTime/1000+"秒");
- }else{
- System.out.println(windowName+"没有取到VIP任务,空闲1秒!");
- commonService();
- }
- }
- });
- }
- }
MainClass类:
- package com.itcast.bank;
- import java.util.concurrent.Executors;
- import java.util.concurrent.TimeUnit;
- public class MainClass {
- public static void main(String[] args) {
- // 循环产生4个普通窗口
- for(int i=1;i<5;i++){
- ServiceWindow commonWindow=new ServiceWindow();
- commonWindow.setWindoeId(i);
- commonWindow.start();//启动这个窗口
- }
- //1个快速窗口
- ServiceWindow expressWindow=new ServiceWindow();
- expressWindow.setType(CustomerType.EXPRESS);
- expressWindow.start();//启动这个窗口
- //1个VIP窗口
- ServiceWindow vipWindow=new ServiceWindow();
- vipWindow.setType(CustomerType.VIP);
- vipWindow.start();//启动这个窗口
- //普通客户拿号
- //定义一个定时线程调度池
- Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
- new Runnable() {
- public void run() {
- //开始取号
- Integer number=NumberMachine.getInstance().getCommonManager().generateNewManager();
- System.out.println("第"+number+"号普通客户正在等待服务!");
- }
- },
- 0,
- Constans.COMMON_CUMSTOMER_INTERVAL_TIME,
- TimeUnit.SECONDS
- );
- //快速客户拿号
- Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
- new Runnable() {
- public void run() {
- //开始取号
- Integer number=NumberMachine.getInstance().getExpressManager().generateNewManager();
- System.out.println("第"+number+"号"+"快速客户正在等待服务!");
- }
- },
- 0,
- Constans.COMMON_CUMSTOMER_INTERVAL_TIME*2,
- TimeUnit.SECONDS
- );
- //vip客户拿号
- Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
- new Runnable() {
- public void run() {
- //开始取号
- Integer number=NumberMachine.getInstance().getVipManager().generateNewManager();
- System.out.println("第"+number+"号"+"VIP客户正在等待服务!");
- }
- },
- 0,
- Constans.COMMON_CUMSTOMER_INTERVAL_TIME*6,
- TimeUnit.SECONDS
- );
- }
- }
- --------------------- ASP.Net+Unity开发、.Net培训、期待与您交流! ----------------------详细请查看:www.itheima.com