黑马日记——银行调度系统

---------------------- android培训 、java培训、期待与您交流!----------------------
一、需求如下:
1,银行内有6个业务窗口,1 - 4号窗口为普通窗口,5号窗口为快速窗口,6号窗口为VIP窗口。
2,有三种对应类型的客户:VIP客户,普通客户,快速客户。
3,异步随机生成各种类型的客户,生成各类型用户的概率比例为:VIP客户 :普通客户 :快速客户  =  1 :6 :3 。
4,客户办理业务所需时间有最大值和最小值,在该范围内随机设定每个VIP客户以及普通客户办理业务所需的时间,快速客户办理业务所需时间为最小值(提示:办理业务的过程可通过线程Sleep的方式模拟)。
5,各类型客户在其对应窗口按顺序依次办理业务。 
6,当VIP(6号)窗口和快速业务(5号)窗口没有客户等待办理业务的,时候,这两个窗口可以处理普通客户的业务,而一旦有对应的客户等待办理业务的时候,则优先处理对应客户的业务。
二、面向对象分析:
1,银行客户排队办理业务通过号机出号,即客户可以用号码来表示,所以需要一个号码生成器来不断生成号码代表客户。
2,由于有队列,就需要一个容器来存储队列,可以使用集合来对排队的号码进行管理,也就需要一个号码管理器,作用是在队列中加入新的号码和移除办理了业务的号码。
3,由于有6个窗口,他们各自有各自的线程,所以采用多线程方式来定义窗口。共有三种类型客户,所以需要定义三种窗口来完成对应客户的业务。
4,因为有三种客户,所以需要定义一个客户类型类,用以匹配对应的窗口和客户,可定义为枚举,分别为类型命名。
5,因为需求要求办理时间为随机,而且产生各种类型客户时间之间有一定比例,所以需要定义一些常量:最大服务时间、最短服务时间,新出现一个普通客户的时间(若1秒产生一个普通客户,那么快速客户为2秒产生一个,VIP客户为6秒产生一个)。
6,主函数需要创建4个普通窗口对象,1个快速窗口对象,1个VIP窗口对象,还要另外设置三个线程来控制普通,快速,VIP客户拿号。
三、深入分析:
通过以上分析,共需要定义六个类:出号机、号码管理器、服务窗口、客户类型枚举、常量类、主函数类。
1,出号机的深入研究:
出号机在本程序中只有一个对象,其内部封装了普通号码管理器,快速号码管理器,VIP号码管理器三个对象。所以本程序将出号机设计为单例。通过对外提供get方法获得出号机对象,从而通过get管理器的方法拿到其内部的相应号码管理器。
2,号码管理器的深入研究:
号码管理器封装一个集合,集合中内容为排队的客户即号码,新出现的号码被添加到集合的最后,服务结束的号码(如果队列中有号码在服务)从集合的首位移除。
3,服务窗口的深入研究:
每个窗口需要单独的线程,所以在创建窗口对象的同时就要开启一个线程,同时,根据客户类型的不同来匹配相应的窗口服务方法,窗口共提供三种服务方法:
普通客户窗口:窗口服务的号码为队列的首位,即集合所移除的号码。然后运行服务时间,服务时间在定义的最大服务时间与最小服务时间内随机生成;若队列中没有需要处理的号码,则让该窗口停滞1秒后重新获取客户。
快速客户窗口:窗口服务的号码为队列的首位,即集合所移除的号码。然后运行服务时间,服务时间为最小服务时间;若队列中没有需要处理的号码,则执行普通客户服务方法。执行结束后重新获取快速客户服务的队列。
VIP客户窗口:窗口服务的号码为队列的首位,即集合所移除的号码。然后运行服务时间,服务时间在定义的最大服务时间与最小服务时间内随机生成;若队列中没有需要处理的号码,则执行普通客户服务方法。执行结束后重新获取VIP客户服务的队列。
4,主函数的深入研究:
主函数分为两个部分:窗口开启运行和客户获取号码。
窗口开启运行:分别创建4个普通窗口对象,1个快速窗口对象,1个VIP窗口对象,并开始他们的线程运行。
客户获取号码:客户拿号也为单独的线程,共有三个线程,分别封装普通客户,快速客户与VIP客户。通过出号机对象中封装的客户号码管理器的添加方法将产生的号码存入队列,这样,当窗口获取到该号码时便开始服务。


注:if...else要比switch效率稍低,原因如下:
if 语句适用范围比较广,只要是 boolean 表达式都可以用 if 判断;而 switch 只能对基本类型进行数值比较。两者的可比性就仅限在两个基本类型比较的范围内。
if 语句每一句都是独立的,例:
if (a == 1) ...
else if (a == 2) ...
a 要被读入寄存器两次,1 和 2 分别被读入寄存器一次。a 读两次是有点多余的,在你全部比较完之前只需要一次读入寄存器就行了,其余都是额外开销。但是 if 语句必须每次都把里面的两个数从内存拿出来读到寄存器,它并不知道其实比较的是同一个 a。
把上面的改成 switch case:
switch (a) {
        case 0:
                break;
        case 1:
}
因为特定的规则,他一开始就知道你要比 a,于是 a 只被一次性读取,相比 if 节约了很多开销。

---------------------- android培训 、java培训、期待与您交流!----------------------

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值