java 銀行業務調度系統

 

模擬實現銀行業務調度系統邏輯,具體需求如下:

銀行內有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);

         }

}  

 

 


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章