天天看點

黑馬程式員_java銀行排程管理系統

---------------------- android教育訓練、java教育訓練、期待與您交流! ----------------------

一、需求分析:

1 銀行内有6個業務視窗,1-4号視窗為普通視窗,5号為快速視窗,6号為VIP視窗。

2 有三種對應類型的客戶:VIP客戶,普通客戶,快速客戶。

3 異異步随機生成各種類型的客戶,生成比例為VIP:普通客戶:快速客戶=1:6:3;

4 客戶辦理業務所需時間有最大值和最小值,在該範圍内随機設定每個VIP客戶以及普通客戶辦理業務所需的時間,快速客戶辦理業務所需時間為最小值

5 各類型客戶在其對應視窗按順序依次辦理業務。

6 當VIP視窗和快速業務視窗沒有客戶等待辦理業務的時候,這兩個視窗可以處理普通客戶的業務,而一旦有對應的客戶辦理業務的時候,則優先處理對應客戶的業務。

7 随機生成客戶時間間隔以及業務辦理時間最大值和最小值自定,可以設定;

8 不要求實習GUI,隻考慮系統邏輯實作,可以通過log方式展現程式運作結果。

二、設計分析:

CustomerType枚舉類

系統中有三種類型的客戶,是以用定義一個枚舉類,其中定義三個成員分别表示三種類型的客戶。

重寫toString方法,傳回類型的中文名稱。這是在後面編碼時重構出來的,剛開始不用考慮。

ServiceWindow類

定義一個start方法,内部啟動一個線程,根據服務視窗的類别分别循環調用三個不同的方法。

定義三個方法分别對三種客戶進行服務,為了觀察運作效果,應詳細列印出其中的細節資訊。

NumberMachine類

定義三個成員變量分别指向三個NumberManager對象,分别表示普通、快速和VIP客戶的号碼管理器,定義三個對應的方法來傳回這三個NumberManager對象。

将NumberMachine類設計成單例。

NumberManager類

定義一個用于存儲上一個客戶号碼的成員變量和用于存儲所有等待服務的客戶号碼的隊列集合。

定義一個産生新号碼的方法和擷取馬上要為之服務的号碼的方法,這兩個方法被不同的線程操作了相同的資料,是以,要進行同步。

代碼如下:

import java.util.concurrent.Executors;

import java.util.concurrent.TimeUnit;

import java.util.logging.Logger;

public class MainClass {

private static Logger logger = Logger.getLogger("cn.itcast.bankqueue");

        public static void main(String[] args) {

//産生4個普通視窗

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

ServiceWindow window =  new ServiceWindow();

window.setNumber(i);

window.start();

}

//産生1個快速視窗

ServiceWindow expressWindow =  new ServiceWindow();

expressWindow.setType(CustomerType.EXPRESS);

expressWindow.start();

//産生1個VIP視窗

ServiceWindow vipWindow =  new ServiceWindow();

vipWindow.setType(CustomerType.VIP);

vipWindow.start();

//普通客戶拿号

Executors.newScheduledThreadPool(1).scheduleAtFixedRate(

new Runnable(){

public void run(){

Integer serviceNumber = NumberMachine.getInstance().getCommonManager().generateNewNumber();

//logger.info("第" + serviceNumber + "号普通客戶正在等待服務!");

System.out.println("第" + serviceNumber + "号普通客戶正在等待服務!");

}

},

0,

Constants.COMMON_CUSTOMER_INTERVAL_TIME,

TimeUnit.SECONDS);

//快速客戶拿号

Executors.newScheduledThreadPool(1).scheduleAtFixedRate(

new Runnable(){

public void run(){

Integer serviceNumber = NumberMachine.getInstance().getExpressManager().generateNewNumber();

System.out.println("第" + serviceNumber + "号快速客戶正在等待服務!");

}

},

0,

Constants.COMMON_CUSTOMER_INTERVAL_TIME * 2,

TimeUnit.SECONDS);

//VIP客戶拿号

Executors.newScheduledThreadPool(1).scheduleAtFixedRate(

new Runnable(){

public void run(){

Integer serviceNumber = NumberMachine.getInstance().getVipManager().generateNewNumber();

System.out.println("第" + serviceNumber + "号VIP客戶正在等待服務!");

}

},

0,

Constants.COMMON_CUSTOMER_INTERVAL_TIME * 6,

TimeUnit.SECONDS);

}

}

NumberManager類:

定義一個用于存儲上一個客戶号碼的成員變量和用于存儲所有等待服務的客戶号碼的隊列集合。

定義一個産生新号碼的方法和擷取馬上要為之服務的号碼的方法,這兩個方法被不同的線程操作了相同的資料,是以,要進行同步

import java.util.ArrayList;

import java.util.List;

public class NumberManager {

private int lastNumber = 0;

private List queueNumbers = new ArrayList();

public synchronized Integer generateNewNumber(){

queueNumbers.add(++lastNumber);

return lastNumber;

}

public synchronized Integer fetchNumber(){

if(queueNumbers.size()>0){

return (Integer)queueNumbers.remove(0);

}else{

return null;

}

}

}

NumberMachine類:

定義三個成員變量分别指向三個NumberManager對象,分别表示普通、快速和VIP客戶的号碼管理器,定義三個對應的方法來傳回這三個NumberManager對象。

将NumberMachine類設計成單例

public class NumberMachine {

private NumberMachine(){}

private static NumberMachine instance = new NumberMachine();

public static NumberMachine getInstance(){

return instance;

}

private NumberManager commonManager = new NumberManager();

private NumberManager expressManager = new NumberManager();

private NumberManager vipManager = new NumberManager();

public NumberManager getCommonManager() {

return commonManager;

}

public NumberManager getExpressManager() {

return expressManager;

}

public NumberManager getVipManager() {

return vipManager;

}

}

CustomerType類:

系統中有三種類型的客戶,是以用定義一個枚舉類,其中定義三個成員分别表示三種類型的客戶。

重寫toString方法,傳回類型的中文名稱。這是在後面編碼時重構出來的,剛開始不用考慮

public enum CustomerType {

COMMON,EXPRESS,VIP;

public String toString(){

String name = null;

switch(this){

case COMMON:

name = "普通";

break;

case EXPRESS:

name = "快速";

break;

case VIP:

name = name();

break;

}

return name;

}

}

ServiceWindow類:

定義一個start方法,内部啟動一個線程,根據服務視窗的類别分别循環調用三個不同的方法。

定義三個方法分别對三種客戶進行服務,為了觀察運作效果,應詳細列印出其中的細節資訊

import java.util.Random;

import java.util.concurrent.Executors;

import java.util.logging.Logger;

public class ServiceWindow {

private static Logger logger = Logger.getLogger("cn.itcast.bankqueue");

private CustomerType type = CustomerType.COMMON;

private int number = 1;

public CustomerType getType() {

return type;

}

public void setType(CustomerType type) {

this.type = type;

}

public void setNumber(int number){

this.number = number;

}

public void start(){

Executors.newSingleThreadExecutor().execute(

new Runnable(){

public void run(){

//下面這種寫法的運作效率低,最好是把while放在case下面

while(true){

switch(type){

case COMMON:

commonService();

break;

case EXPRESS:

expressService();

break;

case VIP:

vipService();

break;

}

}

}

}

);

}

private void commonService(){

String windowName = "第" + number + "号" + type + "視窗";

System.out.println(windowName + "開始擷取普通任務!");

Integer serviceNumber = NumberMachine.getInstance().getCommonManager().fetchNumber();

if(serviceNumber != null ){

System.out.println(windowName + "開始為第" + serviceNumber + "号普通客戶服務");

int maxRandom = Constants.MAX_SERVICE_TIME - Constants.MIN_SERVICE_TIME;

int serviceTime = new Random().nextInt(maxRandom)+1 + Constants.MIN_SERVICE_TIME;

try {

Thread.sleep(serviceTime);

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println(windowName + "完成為第" + serviceNumber + "号普通客戶服務,總共耗時" + serviceTime/1000 + "秒");

}else{

System.out.println(windowName + "沒有取到普通任務,正在空閑一秒");

try {

Thread.sleep(1000);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

private void expressService(){

Integer serviceNumber = NumberMachine.getInstance().getExpressManager().fetchNumber();

String windowName = "第" + number + "号" + type + "視窗";

System.out.println(windowName + "開始擷取快速任務!");

if(serviceNumber !=null){

System.out.println(windowName + "開始為第" + serviceNumber + "号快速客戶服務");

int serviceTime = Constants.MIN_SERVICE_TIME;

try {

Thread.sleep(serviceTime);

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println(windowName + "完成為第" + serviceNumber + "号快速客戶服務,總共耗時" + serviceTime/1000 + "秒");

}else{

System.out.println(windowName + "沒有取到快速任務!");

commonService();

}

}

private void vipService(){

Integer serviceNumber = NumberMachine.getInstance().getVipManager().fetchNumber();

String windowName = "第" + number + "号" + type + "視窗";

System.out.println(windowName + "開始擷取VIP任務!");

if(serviceNumber !=null){

System.out.println(windowName + "開始為第" + serviceNumber + "号VIP客戶服務");

int maxRandom = Constants.MAX_SERVICE_TIME - Constants.MIN_SERVICE_TIME;

int serviceTime = new Random().nextInt(maxRandom)+1 + Constants.MIN_SERVICE_TIME;

try {

Thread.sleep(serviceTime);

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println(windowName + "完成為第" + serviceNumber + "号VIP客戶服務,總共耗時" + serviceTime/1000 + "秒");

}else{

System.out.println(windowName + "沒有取到VIP任務!");

commonService();

}

}

}

Constants類:

l定義三個常量:MAX_SERVICE_TIME、MIN_SERVICE_TIME、COMMON_CUSTOMER_INTERVAL_TIME

public class Constants {

public static int MAX_SERVICE_TIME = 10000; //10秒!

public static int MIN_SERVICE_TIME = 1000; //1秒!

public static int COMMON_CUSTOMER_INTERVAL_TIME = 1;

---------------------- android教育訓練、java教育訓練、期待與您交流! ----------------------