在網上不小心看到《7K面試題銀行業務調度系統實現》,想想反正閑的蛋疼,就練練手吧。
模擬實現銀行業務調度系統邏輯,具體需求如下:
- 銀行內有6個業務窗口,1 - 4號窗口為普通窗口,5號窗口為快速窗口,6號窗口為VIP窗口。
- 有三種對應類型的客戶:VIP客戶,普通客戶,快速客戶(辦理如交水電費、電話費之類業務的客戶)。
- 異步隨機生成各種類型的客戶,生成各類型用戶的概率比例為:
VIP客戶:普通客戶:快速客戶 = 1 :6 :3。
- 客戶辦理業務所需時間有最大值和最小值,在該范圍內隨機設定每個VIP客戶以及普通客戶辦理業務所需的時間,快速客戶辦理業務所需時間為最小值(提示:辦理業務的過程可通過線程Sleep的方式模擬)。
- 各類型客戶在其對應窗口按順序依次辦理業務。
- 當VIP(6號)窗口和快速業務(5號)窗口沒有客戶等待辦理業務的時候,這兩個窗口可以處理普通客戶的業務,而一旦有對應的客戶等待辦理業務的時候,則優先處理對應客戶的業務。
- 隨機生成客戶時間間隔以及業務辦理時間最大值和最小值自定,可以設置。
- 不要求實現GUI,只考慮系統邏輯實現,可通過Log方式展現程序運行結果。
做之前我沒有看人家的實現,做完之后看了,感觸還是挺多哈。人家的實現:http://blog.csdn.net/zhangxiaoxiang/article/details/6294132
我先說下我的思路:
窗口類是獨立的(Windows),客戶是獨立的(Customer),然后有一個維護客戶隊列的類(CustomerQueue),測試類(Main),就這些了。代碼如下:
package com.kawin.bank; import java.util.Random; /** * 辦理業務窗口類 * @author Kawin * */ public class Windows implements Runnable{ public final static int fastestTracationTime = 3000;//最快辦理時間毫秒 public final static int longTracationTime = 20000;//最久辦理時間毫秒 private final static int noCustomerWaitTime = 5000;//沒有人辦理業務時,線程休眠時間 public final static String vipWindow = "VIP"; public final static String commonWindow = "普通"; public final static String speedWindow = "快速"; private String type = "普通";//窗口類型 1普通窗口,2快速窗口,3vip窗口 private String name ; public Windows(String type, String name){ this.type = type; this.name = name; } @Override public void run() { try { while(true){ startTransaction(); } } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } /** * 辦理普通業務 * @throws InterruptedException */ private Customer transactionCommonBiz() throws InterruptedException{ if(CustomerQueue.commonQueue.size() < 1 ) return null; Customer cs = CustomerQueue.commonQueue.take(); long rm = randomTime(longTracationTime); System.out.println(name+"開始辦理->"+cs.getNumber()+"的"+cs.getType()+" 業務...需:"+rm/1000+" 秒"); Thread.sleep(rm); return cs; } /** * 辦理快速業務 * @throws InterruptedException */ private Customer transactionSpeedBiz() throws InterruptedException{ //如果沒有快速客戶,則辦理普通客戶 if(CustomerQueue.speedQueue.size() < 1){ System.out.println(name+"無業務,轉辦理普通業務-->"); return transactionCommonBiz(); }else{ Customer cs = CustomerQueue.speedQueue.take(); System.out.println(name+"開始辦理->"+cs.getNumber()+"的"+cs.getType()+" 業務...需:"+fastestTracationTime/1000+" 秒"); Thread.sleep(fastestTracationTime); return cs; } } /** * 辦理Vip業務 * @throws InterruptedException */ private Customer transactionVipBiz() throws InterruptedException{ //如果沒有vip客戶,則辦理普通客戶 if(CustomerQueue.vipQueue.size() < 1){ System.out.println(name+"無業務,轉辦理普通業務-->"); return transactionCommonBiz(); }else{ Customer cs = CustomerQueue.vipQueue.take(); long rm = randomTime(longTracationTime); System.out.println(name+"開始辦理->"+cs.getNumber()+"的"+cs.getType()+" 業務...需:"+rm/1000+" 秒"); Thread.sleep(rm); return cs; } } /** * 開始辦理業務 * @param args * @throws InterruptedException */ private void startTransaction() throws InterruptedException{ Customer cs = null; if(commonWindow.equals(type)){//普通窗口 cs = transactionCommonBiz(); }else if(speedWindow.equals(type)){//快速窗口 cs = transactionSpeedBiz(); }else{//vip窗口 cs = transactionVipBiz(); } if(null == cs) { System.out.println(name+"無業務,"+noCustomerWaitTime/1000+" 秒后再呼叫!"); Thread.sleep(noCustomerWaitTime); return; } System.out.println(cs.getNumber()+"--"+cs.getType()+" 業務辦理完成!"); } /** * 隨機產生辦理時間 * @return */ private long randomTime(int rm){ return new Random().nextInt(rm); } }
package com.kawin.bank; import java.util.Random; /** * 客戶的父類 * @author Kawin * */ public class Customer{ //客戶類型 public final static String vip = "<VIP>"; public final static String common = "【普通】"; public final static String speed = "[快速]"; private String number;//序列號 private String type ; /** * 按比例生成客戶方法 * VIP客戶 :普通客戶 :快速客戶 = 1 :6 :3。 */ public Customer creatCustomer(){ String customerName = null; Random rm = new Random(); int cs = rm.nextInt(10); if(cs < 1){//vip客戶 customerName = vip; }else if(cs < 4){ customerName = speed; }else{ customerName = common; } this.setType(customerName); return this; } public String getNumber() { return number; } public void setNumber(String number) { this.number = number; } public String getType() { return type; } public void setType(String type) { this.type = type; } public static void main(String[] args) { Customer c = new Customer(); for (int i = 0; i < 1000000; i++) { c.creatCustomer(); } System.out.println(vip); System.out.println(common); System.out.println(speed); } }
package com.kawin.bank; import java.util.Random; import java.util.concurrent.LinkedBlockingQueue; /** * 客戶隊列 * 負責創建客戶及維護客戶 * @author Kawin * */ public class CustomerQueue implements Runnable{ public final static int lastComeTime = 5000;//最大多少毫秒將出現客戶 public static LinkedBlockingQueue<Customer> vipQueue = new LinkedBlockingQueue<Customer>();//vip隊列 public static LinkedBlockingQueue<Customer> commonQueue = new LinkedBlockingQueue<Customer>();//普通隊列 public static LinkedBlockingQueue<Customer> speedQueue = new LinkedBlockingQueue<Customer>();//快速隊列 private static int commonNumber = 1; private static int speedNumber = 1; private static int vipNumber = 1; @Override public void run() { while(true){ try { long willcome = new Random().nextInt(lastComeTime); //System.out.println(willcome/1000 +" 秒后開始按比例創建客戶..."); Thread.sleep(willcome); putQueue(new Customer().creatCustomer());//將創建的客戶放入隊列 } catch (InterruptedException e) { e.printStackTrace(); } } } /** * 將創建的客戶存入不同的隊列 * @param cs * @throws InterruptedException */ private void putQueue(Customer cs) throws InterruptedException{ int curcount = 0; if(Customer.common.equals(cs.getType())){//普通客戶 curcount = commonQueue.size() + vipQueue.size() + speedQueue.size(); cs.setNumber("C"+commonNumber++); commonQueue.put(cs); } else if(Customer.speed.equals(cs.getType())){//快速客戶 curcount = speedQueue.size(); cs.setNumber("S"+speedNumber++); speedQueue.put(cs); } else{//vip客戶 curcount = vipQueue.size(); cs.setNumber("V"+vipNumber++); vipQueue.put(cs); } System.out.println(cs.getNumber() +"--"+ cs.getType() +"客戶, 您好!"+ " 您前面有【" + curcount + "】客戶等待!"); } }
package com.kawin.bank; /** * * @author Kawin 模擬實現銀行業務調度系統邏輯,具體需求如下: *銀行內有6個業務窗口,1 - 4號窗口為普通窗口,5號窗口為快速窗口,6號窗口為VIP窗口。 *有三種對應類型的客戶:VIP客戶,普通客戶,快速客戶(辦理如交水電費、電話費之類業務的客戶)。 *異步隨機生成各種類型的客戶,生成各類型用戶的概率比例為: VIP客戶 :普通客戶 :快速客戶 = 1 :6 :3。 *客戶辦理業務所需時間有最大值和最小值,在該范圍內隨機設定每個VIP客戶以及普通客戶辦理業務所需的時間, 快速客戶辦理業務所需時間為最小值(提示:辦理業務的過程可通過線程Sleep的方式模擬)。 *各類型客戶在其對應窗口按順序依次辦理業務。 當VIP(6號)窗口和快速業務(5號)窗口沒有客戶等待辦理業務的時候,這兩個窗口可以處理普通客戶的業務, 而一旦有對應的客戶等待辦理業務的時候,則優先處理對應客戶的業務。 隨機生成客戶時間間隔以及業務辦理時間最大值和最小值自定,可以設置。 不要求實現GUI,只考慮系統邏輯實現,可通過Log方式展現程序運行結果。 */ public class Main { public static void main(String[] args) { //模擬普通窗口 Thread commonWindow1 = new Thread(new Windows(Windows.commonWindow,"【普通窗口1】")); commonWindow1.start(); Thread commonWindow2 = new Thread(new Windows(Windows.commonWindow,"【普通窗口2】")); commonWindow2.start(); // Thread commonWindow3 = new Thread(new Windows(Windows.commonWindow,"【普通窗口3】")); // commonWindow3.start(); // Thread commonWindow4 = new Thread(new Windows(Windows.commonWindow,"【普通窗口4】")); // commonWindow4.start(); //模擬快速窗口 Thread speedWindow1 = new Thread(new Windows(Windows.speedWindow,"【快速窗口1】")); speedWindow1.start(); //模擬VIP窗口 Thread vipWindow1 = new Thread(new Windows(Windows.vipWindow,"【VIP窗口1】")); vipWindow1.start(); //模擬客戶,根據需要啟用線程 Thread creatCustomerThread1 = new Thread(new CustomerQueue()); creatCustomerThread1.start(); Thread creatCustomerThread2 = new Thread(new CustomerQueue()); creatCustomerThread2.start(); } }
運行結果:
【普通窗口1】無業務,5 秒后再呼叫! 【普通窗口2】無業務,5 秒后再呼叫! 【VIP窗口1】無業務,轉辦理普通業務--> 【VIP窗口1】無業務,5 秒后再呼叫! 【快速窗口1】無業務,轉辦理普通業務--> 【快速窗口1】無業務,5 秒后再呼叫! C1--【普通】客戶, 您好! 您前面有【0】客戶等待! C2--【普通】客戶, 您好! 您前面有【1】客戶等待! C3--【普通】客戶, 您好! 您前面有【2】客戶等待! C4--【普通】客戶, 您好! 您前面有【3】客戶等待! 【普通窗口1】開始辦理->C1的【普通】 業務...需:13 秒 【普通窗口2】開始辦理->C2的【普通】 業務...需:5 秒 【快速窗口1】無業務,轉辦理普通業務--> 【快速窗口1】開始辦理->C3的【普通】 業務...需:9 秒 【VIP窗口1】無業務,轉辦理普通業務--> 【VIP窗口1】開始辦理->C4的【普通】 業務...需:12 秒 S1--[快速]客戶, 您好! 您前面有【0】客戶等待! V1--<VIP>客戶, 您好! 您前面有【0】客戶等待! C5--【普通】客戶, 您好! 您前面有【2】客戶等待! S2--[快速]客戶, 您好! 您前面有【1】客戶等待! C2--【普通】 業務辦理完成! 【普通窗口2】開始辦理->C5的【普通】 業務...需:2 秒 C6--【普通】客戶, 您好! 您前面有【3】客戶等待! C5--【普通】 業務辦理完成! 【普通窗口2】開始辦理->C6的【普通】 業務...需:18 秒 C3--【普通】 業務辦理完成! 【快速窗口1】開始辦理->S1的[快速] 業務...需:3 秒 C7--【普通】客戶, 您好! 您前面有【2】客戶等待! C8--【普通】客戶, 您好! 您前面有【3】客戶等待! S1--[快速] 業務辦理完成! 【快速窗口1】開始辦理->S2的[快速] 業務...需:3 秒 C4--【普通】 業務辦理完成! 【VIP窗口1】開始辦理->V1的<VIP> 業務...需:7 秒 S3--[快速]客戶, 您好! 您前面有【0】客戶等待! C1--【普通】 業務辦理完成! 【普通窗口1】開始辦理->C7的【普通】 業務...需:1 秒 C9--【普通】客戶, 您好! 您前面有【2】客戶等待! C10--【普通】客戶, 您好! 您前面有【3】客戶等待! S2--[快速] 業務辦理完成! 【快速窗口1】開始辦理->S3的[快速] 業務...需:3 秒 C7--【普通】 業務辦理完成! 【普通窗口1】開始辦理->C8的【普通】 業務...需:19 秒 V2--<VIP>客戶, 您好! 您前面有【0】客戶等待! C11--【普通】客戶, 您好! 您前面有【3】客戶等待! S4--[快速]客戶, 您好! 您前面有【0】客戶等待! S3--[快速] 業務辦理完成! 【快速窗口1】開始辦理->S4的[快速] 業務...需:3 秒 C12--【普通】客戶, 您好! 您前面有【4】客戶等待! C13--【普通】客戶, 您好! 您前面有【5】客戶等待! S5--[快速]客戶, 您好! 您前面有【0】客戶等待! C14--【普通】客戶, 您好! 您前面有【7】客戶等待! V1--<VIP> 業務辦理完成! 【VIP窗口1】開始辦理->V2的<VIP> 業務...需:8 秒 S6--[快速]客戶, 您好! 您前面有【1】客戶等待! S4--[快速] 業務辦理完成! 【快速窗口1】開始辦理->S5的[快速] 業務...需:3 秒 C15--【普通】客戶, 您好! 您前面有【7】客戶等待! C16--【普通】客戶, 您好! 您前面有【8】客戶等待! S5--[快速] 業務辦理完成! 【快速窗口1】開始辦理->S6的[快速] 業務...需:3 秒 C17--【普通】客戶, 您好! 您前面有【8】客戶等待! C18--【普通】客戶, 您好! 您前面有【9】客戶等待! C6--【普通】 業務辦理完成! 【普通窗口2】開始辦理->C9的【普通】 業務...需:10 秒 S7--[快速]客戶, 您好! 您前面有【0】客戶等待! S6--[快速] 業務辦理完成! 【快速窗口1】開始辦理->S7的[快速] 業務...需:3 秒 C19--【普通】客戶, 您好! 您前面有【9】客戶等待! V2--<VIP> 業務辦理完成! 【VIP窗口1】無業務,轉辦理普通業務--> 【VIP窗口1】開始辦理->C10的【普通】 業務...需:19 秒 C20--【普通】客戶, 您好! 您前面有【9】客戶等待! S7--[快速] 業務辦理完成! 【快速窗口1】無業務,轉辦理普通業務--> 【快速窗口1】開始辦理->C11的【普通】 業務...需:6 秒 C21--【普通】客戶, 您好! 您前面有【9】客戶等待!