java 银行业务调度系统

来源:互联网 发布:阿里云服务器重启不了 编辑:程序博客网 时间:2024/05/05 10:19

 

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

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

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

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

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

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

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

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

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

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

 

 

思路:

1.一个客户其实就是由银行的取号机生成的一个号码

2.由于客户有三类,每类客户的号码编制都是完全独立的,所以本程序一定要产生三个号码管理器对象,各自管理一类客户的排队号码,这三个号码管理器对象统一由一个取号机来管理,这个取号机对象在整个程序中只能有一个,所以要将其设计为单例

3.各种类型的客户在其对应窗口依次办理业务,准确的说,应该是窗口依次叫号,当一个窗口叫号时,要向对应的号码管理器取号

 

代码如下:
 

public class Constants {

         // 客户办理业务所需时间最小值, 单位为秒

         public static int MIN_SERVICE_TIME = 1;

         // 客户办理业务所需时间最大值

         public static int MAX_SERVICE_TIME = 10;

         // 随机生成普通客户的比例为1

         public static int COMMON_CUSTOMER_INTERVAL_TIME = 1;

}

 

 

public enum CustomerType {

         COMMON, EXPRESS, VIP;

 

         public String toString() {

                   switch (this) {

                   case COMMON:

                            return "普通";

                   case EXPRESS:

                            return "快速";

                   case VIP:

                            return "VIP";

                   }

                   return null;

         }

}

 

 

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() {

                   if (queueNumber.isEmpty()) {

                            return null;

                   }

                   return queueNumber.remove(0);

         }

}

 

 

public class NumberMechine {

         private NumberManager vipNumberManager = new NumberManager();

         private NumberManager commonNumberManager = new NumberManager();

         private NumberManager expressNumberManager = new NumberManager();

 

         public NumberManager getVipNumberManager() {

                   return vipNumberManager;

         }

 

         public NumberManager getCommonNumberManager() {

                   return commonNumberManager;

         }

 

         public NumberManager getExpressNumberManager() {

                   return expressNumberManager;

         }

 

         private NumberMechine() {

         }

 

         private static NumberMechine instance = new NumberMechine();

 

         // 返回取号机实例

         public static NumberMechine getInstance() {

                   return instance;

         }

}

 

 public class ServiceWindow {

         // 取号机

         public static NumberMechine numberMechine = NumberMechine.getInstance();

         // 窗口类型,和客户类型一致,默认为普通类型

         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() {

                            public void run() {

                                     while (true) {

                                               Long serviceTime = (new Random()

                                                                 .nextInt(Constants.MAX_SERVICE_TIME

                                                                                    - Constants.MIN_SERVICE_TIME + 1) + 1) * 1000l;

                                               switch (type) {

                                               case COMMON:

                                                        // 叫号

                                                        service(numberMechine.getCommonNumberManager(),

                                                                           serviceTime, CustomerType.COMMON);

                                                        break;

                                               case EXPRESS:

                                                        boolean flag = service(

                                                                           numberMechine.getExpressNumberManager(),

                                                                           Constants.MIN_SERVICE_TIME * 1000l,

                                                                           CustomerType.EXPRESS);

                                                        // 如果没有快速客户,为普通客户服务

                                                        if (!flag) {

                                                                 service(numberMechine.getCommonNumberManager(),

                                                                                    serviceTime, CustomerType.COMMON);

                                                        }

                                                        break;

                                               case VIP:

                                                        boolean flag2 = service(

                                                                           numberMechine.getVipNumberManager(),

                                                                           serviceTime, CustomerType.VIP);

                                                        // 如果没有VIP客户,为普通客户服务

                                                        if (!flag2) {

                                                                 service(numberMechine.getCommonNumberManager(),

                                                                                    serviceTime, CustomerType.COMMON);

                                                        }

                                                        break;

                                               }

                                     }

                            }

                   });

         }

 

         private boolean service(NumberManager numberManager, Long serviceTime,

                            CustomerType customerType) {

                   // 叫号

                   Integer number = numberManager.fetchServiceNumber();

                   System.out.println(windowId + "号" + type + "窗口开始获取" + customerType

                                     + "任务");

                   // 如果没有叫到号,休息一秒

                   if (number == null) {

                            // 如果叫的号是普通客户并且没有叫到,说明银行现在没有排队的客户,空闲1秒

                            if (customerType == CustomerType.COMMON) {

                                     System.out.println(windowId + "号" + type + "窗口没有获取到"

                                                        + customerType + "任务,正在空闲一秒");

                                     try {

                                               Thread.sleep(1000);

                                     } catch (InterruptedException e) {

                                               e.printStackTrace();

                                     }

                                     return false;

                            }

                            System.out.println(windowId + "号" + type + "窗口没有获取到" + customerType

                                               + "任务");

                            return false;

                   } else {// 如果叫到了号,就开始为客户服务

                            System.out.println(windowId + "号" + type + "窗口开始为" + number + "号"

                                               + customerType + "客户服务");

                            // 开始时间

                            Long biginTime = System.currentTimeMillis();

                            try {

                                     Thread.sleep(serviceTime);

                            } catch (InterruptedException e) {

                                     e.printStackTrace();

                            }

                            // 本次服务所用的时间

                            Long costTime = System.currentTimeMillis() - biginTime;

                            System.out.println(windowId + "号" + type + "窗口为" + number + "号"

                                               + customerType + "客户服务完成,耗时" + costTime / 1000 + "秒");

                            return true;

                   }

         }

}

 

   

public class MainClass {

         public static void main(String[] args) {

                   // 开启4个普通窗口

                   for (int i = 1; i <= 4; i++) {

                            ServiceWindow commonServiceWindow = new ServiceWindow();

                            commonServiceWindow.setWindowId(i);

                            commonServiceWindow.start();

                   }

 

                   // 开启1个快速窗口

                   ServiceWindow expressServiceWindow = new ServiceWindow();

                   expressServiceWindow.setType(CustomerType.EXPRESS);

                   expressServiceWindow.start();

 

                   // 开启1个VIP窗口

                   ServiceWindow vipServiceWindow = new ServiceWindow();

                   vipServiceWindow.setType(CustomerType.VIP);

                   vipServiceWindow.start();

 

                   // 制造普通客户

                   Executors.newScheduledThreadPool(1).scheduleAtFixedRate(new Runnable() {

                            public void run() {

                                     NumberMechine.getInstance().getCommonNumberManager().generateNewNumber();

                            }

                   }, 0, Constants.COMMON_CUSTOMER_INTERVAL_TIME, TimeUnit.SECONDS);

 

                   // 制造快速客户

                   Executors.newScheduledThreadPool(1).scheduleAtFixedRate(new Runnable() {

                            public void run() {

                                     NumberMechine.getInstance().getExpressNumberManager().generateNewNumber();

                            }

                   }, 0, Constants.COMMON_CUSTOMER_INTERVAL_TIME * 3, TimeUnit.SECONDS);

 

                   // 制造vip客户

                   Executors.newScheduledThreadPool(1).scheduleAtFixedRate(new Runnable() {

                            public void run() {

                                     NumberMechine.getInstance().getVipNumberManager().generateNewNumber();

                            }

                   }, 0, Constants.COMMON_CUSTOMER_INTERVAL_TIME * 6, TimeUnit.SECONDS);

         }

}