——銀行業務調度系統

---------------------- <a href="http://www.itheima.com"target="blank">ASP.Net+Unity開發</a>、<a href="http://www.itheima.com"target="blank">.Net培訓</a>、期待與您交流! ----------------------

銀行業務調度系統

需求:

   1,銀行內有6個業務窗口,1-4號窗口爲普通窗口,5號窗口爲快速窗口,

6號窗口爲VIP窗口。

   2,有三種對應類型的客戶:VIP,普通客戶,快速客戶(辦理如交水電費,話費之類的業務的客戶)。

   3,異步隨機生成各種業務類型的客戶,生成各類型的客戶的比例爲:

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

   4,客戶辦理業務所需時間有最大值和最小值,在該範圍內隨機設定每個VIP客戶

以及普通客戶辦理業務所需的時間,快速客戶辦理業務所需的時間爲最小值。

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

   6,當VIP(6號)窗口和快速業務(5號)窗口沒有客戶等待辦理業務的時候,

這兩個窗口可以處理普通客戶的業務,而一旦有對應的客戶等待辦理業務時,則優先處理對應客戶的業務。

   7,隨機生成客戶的時間間隔及業務辦理時間的最大值和最小值自定。


分析:

1,客戶:要去銀行辦理業務的人。

2,取號:去銀行辦理業務的時候,都會取票排隊,所以有一個取票器。

3,出票:而不同的客戶辦理的業務也是不同的,按需求分出了三類客戶,那麼就有三個產生不同類型票號的票號管理器。

4,辦理業務:顧客取到號排隊後,交道號之後就要去辦理業務,所以要有辦理業務的窗口。

客戶:

1,因爲客戶要辦理的業務是不同的,但客戶的類型是固定的,所以要有一個用於描述客戶的類。

        取號:

1,客戶來了之後就要取票辦理業務,所以取票器要有產生客戶號的方法;

2,而客戶的數量是不固定的,所以取票器要有一個集合來存儲客戶。

3,當一個顧客辦理完業務之後,就要把後面的客戶的排隊順序向前移一位,所以要有一個移出辦理業務結束的客戶的方法。

出票:

1,因爲業務的不同,所以取票器中,要有三個不同的票號管理器;

辦理業務:

1,窗口會定時的叫號,對應業務的客戶被叫到號後就會到對應的窗口辦理業務,這就要問出票器有沒有對應的票號;

2,窗口辦理完業務之後,就會要叫下一個號,如果快速窗口和VIP窗口沒有客戶,則就去辦理普通業務。

對應類的示例代碼:

票號管理器類:

 爲客戶生產對應類型業務的票號,當客戶辦理完業務時,取出對應的票號。

package com.itheima.bank;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 票號管理器
 * @author wuyong
 *
 */
public class NOManager {
	//票號
	private Integer lastNO = 1;
	private List queueNos = new ArrayList();
	/**
	 * 創建票號
	 * @return
	 */
	public synchronized Integer generateNewNO(){
		queueNos.add(lastNO);
		return lastNO ++;
	}
	
	/**
	 * 獲得當前服務的號碼
	 * @return
	 */
	public synchronized Integer fetchServiceNO(){
		if (queueNos.size() > 0) 
			return queueNos.remove(0);
		return null;
	}
}

取票器類:

因爲,每一個客戶到銀行取號,都是到取票器取號的,所以取票器用單例設計。

package com.itheima.bank;

/**
 * 出票器。
 * @author wuyong
 *
 */
public class NOMachine {
	//普通的票號管理器
	private NOManager commonManager = new NOManager();
	//快速的票號管理器
	private NOManager expressManager = new NOManager();
	//VIP的票號管理器
	private NOManager vipManager = new NOManager();
	
	public NOManager getCommonManager() {
		return commonManager;
	}

	public NOManager getExpressManager() {
		return expressManager;
	}

	public NOManager getVipManager() {
		return vipManager;
	}
	/**
	 * 單例模式
	 */
	private static final NOMachine instance = new NOMachine();
	private NOMachine(){}
	public static NOMachine getInsatnce(){
		return instance;
	}
}

服務窗口類:

  生產4個普通窗口,1個快速窗口,1個VIP窗口,辦理三種類型的業務。

package com.itheima.bank;

import java.util.Random;
import java.util.concurrent.Executors;

/**
 * 窗口
 * @author wuyong
 *
 */
public class ServiceWindow {
	//用戶的類型
	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;
	}
	//取票器
	private NOMachine noMachine = NOMachine.getInsatnce();
	
	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() {
		Integer no = noMachine.getCommonManager().fetchServiceNO();
		String windowName = "第" + windowId + "號" + type +"窗口";
		System.out.println(windowName + "正在獲取任務");
		if (no != null) {
			System.out.println(windowName + "開始爲第" + no + "個普通客戶服務");
			long startTime = System.currentTimeMillis();
			int maxServiceTime = Constants.MAX_SERVICE_TIME - Constants.MIN_SERVICE_TIME;
			int serviceTime = new Random().nextInt(maxServiceTime) + Constants.MIN_SERVICE_TIME;
			try {
				Thread.sleep(serviceTime);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			int usedTime = (int)(System.currentTimeMillis() - startTime) / 1000;
			System.out.println(windowName + "爲第" + no + "個普通客戶完成了業務,耗時:" + usedTime + "秒");
		}
		else {
			System.out.println(windowName + "沒有獲得任務!空閒一秒鐘!");
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
	

	private void expressService() {
		Integer no = noMachine.getExpressManager().fetchServiceNO();
		String windowName = "第" + windowId + "號" + type +"窗口";
		System.out.println(windowName + "正在獲取任務");
		if (no != null) {
			System.out.println(windowName + "開始爲第" + no + "個快速客戶服務");
			long startTime = System.currentTimeMillis();
			long serviceTime = Constants.MIN_SERVICE_TIME;
			try {
				Thread.sleep(serviceTime);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			int usedTime = (int)(System.currentTimeMillis() - startTime) / 1000;
			System.out.println(windowName + "爲第" + no + "個快速客戶完成了業務,耗時:" + usedTime + "秒");
		}
		else {
			System.out.println(windowName + "沒有獲得任務!");
			commonService();
		}
	}

	private void vipService() {
		String windowName = "第" + windowId + "號" + type +"窗口";
		Integer no = noMachine.getVipManager().fetchServiceNO();
		System.out.println(windowName + "正在獲取任務");
		if (no != null) {
			System.out.println(windowName + "開始爲第" + no + "個VIP客戶服務");
			long startTime = System.currentTimeMillis();
			int maxServiceTime = Constants.MAX_SERVICE_TIME - Constants.MIN_SERVICE_TIME;
			int serviceTime = new Random().nextInt(maxServiceTime) + Constants.MIN_SERVICE_TIME;
			try {
				Thread.sleep(serviceTime);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			int usedTime = (int)(System.currentTimeMillis() - startTime) / 1000;
			System.out.println(windowName + "爲第" + no + "個VIP客戶完成了業務,耗時:" + usedTime + "秒");
		}
		else {
			System.out.println(windowName + "沒有獲得任務!");
			commonService();
		}
	}
}

客戶類型枚舉:
用於表示客戶的類型,以及其辦理業務鎖對應的窗口
package com.itheima.bank;

/**
 * 客戶類型
 * 類型爲枚舉
 * @author wuyong
 *
 */
public enum CustomerType {
	COMMON,EXPRESS,VIP;
	//獲取對應類型的名稱
	public String toString(){
		switch(this){
			case COMMON:
				return "普通";
			case EXPRESS:
				return "快速";
			case VIP:
				return name();
		}
		return null;
	}
}

服務用時類:
設定服務時間的最大值和最小值
package com.itheima.bank;

/**
 * 服務時間的相關信息
 * @author wuyong
 *
 */
public class Constants {
	//服務的最大時間
	public static int  MAX_SERVICE_TIME = 10 * 1000;
	//服務的最小時間
	public static int MIN_SERVICE_TIME = 1 * 1000;
	//普通客戶出現的時間
	public static int COMMON_SREVICE_TIME = 1;
}

主函數類:
 模擬銀行辦理業務
package com.itheima.bank;

import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
 * 主線程類
 * @author wuyong
 *
 */
public class MainClass {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		//1~4號普通窗口
		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() {
					@Override
					public void run() {
						Integer no = NOMachine.getInsatnce().getCommonManager().generateNewNO();
						System.out.println(no + "號普通客戶等待服務。。。");
					}
				}, 
				0, 
				Constants.COMMON_SREVICE_TIME, 
				TimeUnit.SECONDS);
		
		//定時生產一個VIP客戶,等待服務
		Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
				new Runnable() {
					@Override
					public void run() {
						Integer no = NOMachine.getInsatnce().getVipManager().generateNewNO();
						System.out.println(no + "號VIP客戶等待服務。。。");
					}
				}, 
				0, 
				Constants.COMMON_SREVICE_TIME * 6, 
				TimeUnit.SECONDS);
		
		//定時生產一個快速客戶,等待服務
		Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
				new Runnable() {
					@Override
					public void run() {
						Integer no = NOMachine.getInsatnce().getExpressManager().generateNewNO();
						System.out.println(no + "號快速客戶等待服務。。。");
					}
				}, 
				0, 
				Constants.COMMON_SREVICE_TIME * 3, 
				TimeUnit.SECONDS);
	}

}


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