---------------------- android培訓 、java培訓 、期待與您交流! ----------------------
銀行業務調度系統
業務需求:
模擬實現銀行業務調度系統邏輯,具體需求如下:
銀行內有6個業務窗口,1 - 4號窗口爲普通窗口,5號窗口爲快速窗口,6號窗口爲VIP窗口。
有三種對應類型的客戶:VIP客戶,普通客戶,快速客戶(辦理如交水電費、電話費之類業務的客戶)。
異步隨機生成各種類型的客戶,生成各類型用戶的概率比例爲:
VIP客戶 :普通客戶 :快速客戶 = 1 :6 :3。
客戶辦理業務所需時間有最大值和最小值,在該範圍內隨機設定每個VIP客戶以及普通客戶辦理業務所需的時間,快速客戶辦理業務所需時間爲最小值(提示:辦理業務的過程可通過線程Sleep的方式模擬)。
各類型客戶在其對應窗口按順序依次辦理業務。
當VIP(6號)窗口和快速業務(5號)窗口沒有客戶等待辦理業務的時候,這兩個窗口可以處理普通客戶的業務,而一旦有對應的客戶等待辦理業務的時候,則優先處理對應客戶的業務。
隨機生成客戶時間間隔以及業務辦理時間最大值和最小值自定,可以設置。
不要求實現GUI,只考慮系統邏輯實現,可通過Log方式展現程序運行結果。
項目分析
主要類 號碼產生類 服務號碼管理類 服務窗口類 測試類
號碼產生類
負責產生號碼 ,定義一個集合,把產生的號碼加入集合中,當爲最前面號碼服務的時候,刪除集合最前面的號碼。
服務號碼管理類:
要產生3種類型的號碼,所以定義類型爲號碼產生類 類型的3個屬性。用單例產生他們的對象
服務窗口類
分爲普通窗口 ,快速窗口 , vip窗口。窗口的類型可以通過專門建立一個枚來定義。
定義一個線程池來管理窗口的業務。普通窗口爲普通號碼服務,當沒有普通客戶的時候,休息一秒中。
快速窗口和vip窗口首先爲各自對應的號碼服務,當沒有的對應的號碼的時候,可以爲普通號碼服務。
因此,可以建立普通窗口業務方法,快速窗口業務方法,vip窗口業務方法,處理對應的業務,
當快速窗口和vip窗口沒有對應的號碼的時候調用普通窗口業務方法處理普通號碼。
項目實現
//號碼產生類
public class NumberManager {
//服務號碼
private int lastNameber = 1;
private List<Integer> queueNumber = new ArrayList<Integer>();
//產生號碼,並把號碼裝進集合
public synchronized Integer genrateNewManager() {
queueNumber.add(lastNameber);
return lastNameber++;
}
// 獲取馬上需要服務的號碼
public synchronized Integer fetchNumber() {
Integer number =null;
//如果號碼不爲空,刪除最前面的號碼,並返回最前面的號碼
if(queueNumber.size()>0){
return queueNumber.remove(0);
}
return number;
}
}
//號碼管理類
public class NumberMachine {
//普通號碼
private NumberManager commonManager =new NumberManager();
//快速服務號碼
private NumberManager expressManager =new NumberManager();
//vip號碼
private NumberManager vipManager =new NumberManager();
//我們用單例來產生號碼
private NumberMachine(){}
private static NumberMachine instance = new NumberMachine();
public static NumberMachine getInstance(){
return instance;
}
public NumberManager getCommonManager() {
return commonManager;
}
public void setCommonManager(NumberManager commonManager) {
this.commonManager = commonManager;
}
public NumberManager getExpressManager() {
return expressManager;
}
public void setExpressManager(NumberManager expressManager) {
this.expressManager = expressManager;
}
public NumberManager getVipManager() {
return vipManager;
}
public void setVipManager(NumberManager vipManager) {
this.vipManager = vipManager;
}
}
//服務窗口類
public class ServiceWindow {
//窗口類型,用枚舉表示
private CustomerType type = CustomerType.COMMON;
//窗口id
private int windowId = 1;
//
public void start() {
Executors.newSingleThreadExecutor().execute(new Runnable() {
public void run() {
while (true) {
switch (type) {
case COMMON:
commonService();
break;
case EXPRESS:
expressService();
break;
case VIP:
vipService();
break;
}
}
}
});
}
//普通窗口
private void commonService() {
String windowName = "第" + windowId + "號" + type + "窗口";
Integer number = NumberMachine.getInstance().getCommonManager()
.fetchNumber();
System.out.println(windowName + "正在獲取普通任務");
//當票號不爲空時,開始服務
if (number != null) {
System.out.println(windowName + "正在爲爲第" + number + "個" + "普通"
+ "客戶服務");
//設置隨機服務時間
long beginTime = System.currentTimeMillis();
int maxRand = Constans.MAX_SERVICE_TIME - Constans.MIN_SERVICE_TIME;
long serverTime = new Random().nextInt(maxRand) + 1
+ Constans.MIN_SERVICE_TIME;
try {
Thread.sleep(serverTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
long costTime = System.currentTimeMillis() - beginTime;
System.out.println(windowName + "爲第" + number + "個" + "普通"
+ "客戶完成服務," + "耗時" + costTime / 1000 + "秒");
} else {
//當沒有客戶時,休息一秒在叫號
System.out.println(windowName + "沒有取到普通任務,休息一秒");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
//快速服務窗口
private void expressService() {
String windowName = "第" + windowId + "號" + type + "窗口";
Integer number = NumberMachine.getInstance().getExpressManager()
.fetchNumber();
System.out.println(windowName + "正在獲取任務");
//當有快速客戶時爲快速客戶服務
if (number != null) {
System.out.println(windowName + "正在爲爲第" + number + "個" + type
+ "客戶服務");
try {
Thread.sleep(Constans.MIN_SERVICE_TIME);
} catch (InterruptedException e) {
e.printStackTrace();
}
long costTime = Constans.MIN_SERVICE_TIME;
System.out.println(windowName + "爲第" + number + "個" + type
+ "客戶完成服務," + "耗時" + costTime / 1000 + "秒");
} else {
//當沒有快速客戶時,可以爲普通客戶服務
System.out.println(windowName + "沒有取到任務");
commonService();
}
}
//vip服務窗口
private void vipService() {
String windowName = "第" + windowId + "號" + type + "窗口";
Integer number = NumberMachine.getInstance().getVipManager()
.fetchNumber();
System.out.println(windowName + "正在獲取任務");
//當有vip客戶時爲vip客戶服務
if (number != null) {
System.out.println(windowName + "正在爲爲第" + number + "個" + type
+ "客戶服務");
long beginTime = System.currentTimeMillis();
int maxRand = Constans.MAX_SERVICE_TIME - Constans.MIN_SERVICE_TIME;
long serverTime = new Random().nextInt(maxRand) + 1
+ Constans.MIN_SERVICE_TIME;
try {
Thread.sleep(serverTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
long costTime = System.currentTimeMillis() - beginTime;
System.out.println(windowName + "爲第" + number + "個" + type
+ "客戶完成服務," + "耗時" + costTime / 1000 + "秒");
} else {
//當沒有vip客戶時,可以爲普通客戶服務
System.out.println(windowName + "沒有取到任務");
commonService();
}
}
public CustomerType getType() {
return type;
}
public void setType(CustomerType type) {
this.type = type;
}
public int getWindowId() {
return windowId;
}
public void setWindowId(int windowId) {
this.windowId = windowId;
}
}
//創建枚舉 設定 窗口類型
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 Constans {
//服務最大時間
public static int MAX_SERVICE_TIME=10000;
//服務最小時間
public static int MIN_SERVICE_TIME=1000;
}
//測試類
public class BankTest {
public static void main(String[] args) {
//產生普通窗口
for (int i = 1; i < 5; i++) {
ServiceWindow commonWindow = new ServiceWindow();
commonWindow.setWindowId(i);
commonWindow.start();
}
//產生快速服務窗口
ServiceWindow expressWindow = new ServiceWindow();
expressWindow.setType(CustomerType.EXPRESS);
expressWindow.start();
//產生vip服務窗口
ServiceWindow vipWindow = new ServiceWindow();
vipWindow.setType(CustomerType.VIP);
vipWindow.start();
//用線程池管理號碼的產生,每隔一段時間重新調用方法,就可以循環產生號碼
Executors.newScheduledThreadPool(1).scheduleAtFixedRate(new Runnable() {
public void run() {
//產生普通客戶號碼,每過1秒產生普通號碼
Integer number = NumberMachine.getInstance().getCommonManager().genrateNewManager();
System.out.println(number+"普通客戶等待服務");
}
}, 0, 1, TimeUnit.SECONDS);
Executors.newScheduledThreadPool(1).scheduleAtFixedRate(new Runnable() {
public void run() {
//產生快速客戶號碼 每過2秒產生快速服務號碼
Integer number = NumberMachine.getInstance().getVipManager().genrateNewManager();
System.out.println(number+"快速客戶等待服務");
}
}, 0, 2, TimeUnit.SECONDS);
Executors.newScheduledThreadPool(1).scheduleAtFixedRate(new Runnable() {
public void run() {
//產生vip客戶號碼 每過6秒產生vip號碼
Integer number = NumberMachine.getInstance().getVipManager().genrateNewManager();
System.out.println(number+"VIP客戶等待服務");
}
}, 0, 6, TimeUnit.SECONDS);
}
}
---------------------- android培訓 、java培訓 、期待與您交流! ----------------------