銀行業務調度系統

銀行業務調度系統

調度線程池(按固定頻率執行指定代碼)

 

面向對象分析:

         三個類型的客戶:VIP客戶,普通客戶,快速客戶

 

號碼管理器

有三個號碼管理器,由一個號碼機器管理

         兩個成員變量int 類型lastNumber即最後服務的號碼

         集合類型,queueNumber  服務隊列

         兩個方法:

                   因爲下面兩個方法是兩個線程操作同一資源,所以加synchronized 上鎖

1,  generateNumber();客戶獲得服務號碼,開始排隊

2,  fetchNumber();服務窗口叫號給對應客戶辦理業務

import java.util.ArrayList;
import java.util.List;

public class NumberManager {

	// 代碼管理器,出號碼
	private int lastNumber = 1;
	// 定義一個集合,模擬排隊取號
	private List<Integer> queueNumber = new ArrayList<Integer>();

	// 獲得號碼,將號碼存入集合中,開始排隊
	public synchronized Integer generateNewManager() {
		queueNumber.add(lastNumber);
		return lastNumber++;
	}

	// 服務窗口叫號服務
	// 返回值封裝成包裝類,防止空指針異常
	public synchronized Integer fetchServiceNumber() {
		if (queueNumber.size() > 0) {
			return queueNumber.remove(0);
		}
		return null;
	}
}


號碼機器:(需要設計成單例)

         getCommonManager();獲取普通號碼管理器

         getVipManager();獲取VIP號碼管理器

         getExpressManager();獲取快速號碼管理器

         getInstance();獲取號碼機器實例,因爲只有一個機器,使用單立設計模式

//號碼機器,管理三個號碼管理器
public class NumberMachine {

	private static NumberMachine nm = new NumberMachine();
	// 三個成員,分別爲普通號碼,vip號碼,快速號碼
	private NumberManager commonManager = new NumberManager();
	private NumberManager vipManager = new NumberManager();
	private NumberManager expressManager = new NumberManager();

	// 單例,構造方法私有
	private NumberMachine() {
	}

	public static NumberMachine getInstance() {
		return nm;
	}

	// 獲取普通取號器實例
	public NumberManager getCommonManager() {
		return commonManager;
	}

	// 獲取vip取號器實例
	public NumberManager getVipManager() {
		return vipManager;
	}

	// 獲取快速取號器實例
	public NumberManager getExpressManager() {
		return expressManager;
	}

}


服務窗口:

         ServiceWindow

                   Start();開始服務

下面三個方法分別代表三類服務

                   commonService();普通服務

                   expressService();快速服務

                   vipService();vip服務

 

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

//服務窗口
public class ServiceWindow {

	// 窗口類型,默認爲普通窗口
	private Customer type = Customer.COMMON;
	// 窗口號,如:普通窗口就有4個,分別爲1,2,3,4。默認爲1
	private int windowId = 1;

	// 窗口開始辦理業務
	public void start() {

		// jdk1.5特性,創建線程,從線程池裏面直接取
		Executors.newSingleThreadExecutor().execute(new Runnable() {
			public void run() {
				while (true) {
					switch (type) {
					case COMMON:
						commonService();
						break;
					case EXPRESS:
						expressService();
						break;
					case VIP:
						vipService();
						break;
					}
				}
			}
		});
	}

	// 普通服務
	public void commonService() {
		// 通過號碼機器獲得普通號碼管理器,並叫號
		System.out.println(windowId + "號" + type + "窗口正在等待服務");
		Integer number = NumberMachine.getInstance().getCommonManager()
				.fetchServiceNumber();
		if (number != null) {
			System.out.println(windowId + "號" + type + "窗口開始給" + number + "號普通客戶服務");
			long startTime = System.currentTimeMillis();
			// 最大隨機值應該是10000到1000之間
			int maxServiceTime = Constants.MAX_SERVICE_TIME
					- Constants.MIN_SERVICE_TIME;
			// 獲取服務時間,線程sleep(),模擬服務
			long serverTime = new Random().nextInt(maxServiceTime) + 1
					+ Constants.MIN_SERVICE_TIME;
			try {
				Thread.sleep(serverTime);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			long costTime = System.currentTimeMillis() - startTime;
			// 取到要服務的號碼,開始服務
			System.out.println(windowId + "號" + type + "窗口給" + number
					+ "號普通客戶服務完,耗時" + costTime / 1000 + "秒");
		} else {
			// 窗口沒取到號,休息1秒
			System.out.println(windowId + "窗口沒有普通服務,休息一秒");
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}

	// vip服務
	public void vipService() {
		// 通過號碼機器獲得普通號碼管理器,並叫號
		System.out.println(windowId + "號" + type + "窗口正在等待服務");
		Integer number = NumberMachine.getInstance().getVipManager()
				.fetchServiceNumber();
		if (number != null) {
			System.out.println(windowId + "號" + type + "窗口開始給" + number + "號vip客戶服務");
			long startTime = System.currentTimeMillis();
			// 最大隨機值應該是10000到1000之間
			int maxServiceTime = Constants.MAX_SERVICE_TIME
					- Constants.MIN_SERVICE_TIME;
			// 獲取服務時間,線程sleep(),模擬服務
			long serverTime = new Random().nextInt(maxServiceTime) + 1
					+ Constants.MIN_SERVICE_TIME;
			try {
				Thread.sleep(serverTime);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			long costTime = System.currentTimeMillis() - startTime;
			// 取到要服務的號碼,開始服務
			System.out.println(windowId + "號" + type + "窗口給" + number
					+ "號vip客戶服務完,耗時" + costTime / 1000 + "秒");
		} else {
			// 窗口沒取到號,繼續普通服務
			System.out.println(windowId + "窗口沒有vip服務,開始取普通服務");
			commonService();
		}
	}

	// 快速服務
	public void expressService() {
		// 通過號碼機器獲得普通號碼管理器,並叫號
		System.out.println(windowId + "號" + type + "窗口正在等待服務");
		Integer number = NumberMachine.getInstance().getExpressManager()
				.fetchServiceNumber();
		if (number != null) {
			System.out.println(windowId + "號" + type + "窗口開始給" + number + "號快速客戶服務");
			long startTime = System.currentTimeMillis();
			// 獲取服務時間,線程sleep(),模擬服務
			// 快速服務時間爲最小服務時間
			long serverTime = Constants.MIN_SERVICE_TIME;
			try {
				Thread.sleep(serverTime);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			long costTime = System.currentTimeMillis() - startTime;
			// 取到要服務的號碼,開始服務
			System.out.println(windowId + "號" + type + "窗口給" + number
					+ "號快速客戶服務完,耗時" + costTime / 1000 + "秒");
		} else {
			// 窗口沒取到號,繼續普通服務
			System.out.println(windowId + "窗口沒有快速服務,開始取普通服務");
			commonService();
		}
	}

	// 銀行窗口可能改變,如普通窗口可以換成VIP窗口
	public void setType(Customer type) {
		this.type = type;
	}

	// 窗口號也可設置,如1,2號窗口可以互換編號
	public void setWindowId(int windowId) {
		this.windowId = windowId;
	}

}

場景類:

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

public class MainClass {

	public static void main(String[] args) {
		// 先創建4個普通窗口
		for (int i = 1; i < 5; i++) {
			ServiceWindow comWindow = new ServiceWindow();
			comWindow.setWindowId(i);
			comWindow.start();
		}
		// 創建vip窗口
		ServiceWindow vipWindow = new ServiceWindow();
		vipWindow.setType(Customer.VIP);
		vipWindow.setWindowId(5);
		vipWindow.start();
		// 創建快速窗口
		ServiceWindow expressWindow = new ServiceWindow();
		expressWindow.setType(Customer.EXPRESS);
		expressWindow.setWindowId(6);
		expressWindow.start();

		// 創建線程,模擬來的客戶,使用線程調度池,不停的執行指定代碼
		// 模擬普通客戶
		Executors.newScheduledThreadPool(1).scheduleAtFixedRate(new Runnable() {
			public void run() {

				Integer number = NumberMachine.getInstance().getCommonManager()
						.generateNewManager();
				System.out.println("第" + number + "號普通客戶來了,等待服務");
			}
		}, 0, Constants.COMMON_CUSTOMER_INTERVAL_TIME, TimeUnit.SECONDS);
		// 模擬vip客戶
		Executors.newScheduledThreadPool(1).scheduleAtFixedRate(new Runnable() {

			public void run() {
				Integer number = NumberMachine.getInstance().getVipManager()
						.generateNewManager();
				System.out.println("第" + number + "號vip客戶來了,等待服務");
			}
		}, 0, Constants.COMMON_CUSTOMER_INTERVAL_TIME * 6, TimeUnit.SECONDS);
		// 模擬快速客戶
		Executors.newScheduledThreadPool(1).scheduleAtFixedRate(new Runnable() {

			public void run() {
				Integer number = NumberMachine.getInstance()
						.getExpressManager().generateNewManager();
				System.out.println("第" + number + "號快速客戶來了,等待服務");
			}
		}, 0, Constants.COMMON_CUSTOMER_INTERVAL_TIME * 2, TimeUnit.SECONDS);
	}
}

常量類:

public class Constants {

	// 最大服務時間
	public static int MAX_SERVICE_TIME = 10000;
	// 最小服務時間
	public static int MIN_SERVICE_TIME = 1000;
//	普通客戶來的時間
	public static int COMMON_CUSTOMER_INTERVAL_TIME = 1;
}
客戶類(枚舉):

public enum Customer {

	VIP, COMMON, EXPRESS;

	public String toString() {
		switch (this) {
		case COMMON:
			return "普通";
		case EXPRESS:
			return "快速";
		case VIP:
			return name();
		}
		return null;
	}
}



代碼優化:

可以將vip窗口,和快速窗口設計成普通窗口的子類,

只需從寫普通服務commonService()方法中的部分代碼即可

提高代碼複用性


運行結果:

1號普通窗口正在等待服務
1窗口沒有普通服務,休息一秒
4號普通窗口正在等待服務
4窗口沒有普通服務,休息一秒
5號VIP窗口正在等待服務
5窗口沒有vip服務,開始取普通服務
5號VIP窗口正在等待服務
5窗口沒有普通服務,休息一秒
2號普通窗口正在等待服務
2窗口沒有普通服務,休息一秒
3號普通窗口正在等待服務
3窗口沒有普通服務,休息一秒
第1號vip客戶來了,等待服務
第1號快速客戶來了,等待服務
6號快速窗口正在等待服務
6號快速窗口開始給1號快速客戶服務
第1號普通客戶來了,等待服務
5號VIP窗口正在等待服務
1號普通窗口正在等待服務
1號普通窗口開始給1號普通客戶服務
4號普通窗口正在等待服務
4窗口沒有普通服務,休息一秒
5號VIP窗口開始給1號vip客戶服務
第2號普通客戶來了,等待服務
2號普通窗口正在等待服務
3號普通窗口正在等待服務
3號普通窗口開始給2號普通客戶服務
2窗口沒有普通服務,休息一秒
6號快速窗口給1號快速客戶服務完,耗時1秒
6號快速窗口正在等待服務
6窗口沒有快速服務,開始取普通服務
6號快速窗口正在等待服務
6窗口沒有普通服務,休息一秒
4號普通窗口正在等待服務
4窗口沒有普通服務,休息一秒
第3號普通客戶來了,等待服務
2號普通窗口正在等待服務
2號普通窗口開始給3號普通客戶服務
第2號快速客戶來了,等待服務
6號快速窗口正在等待服務
6號快速窗口開始給2號快速客戶服務
3號普通窗口給2號普通客戶服務完,耗時1秒
3號普通窗口正在等待服務
3窗口沒有普通服務,休息一秒
4號普通窗口正在等待服務
4窗口沒有普通服務,休息一秒
第4號普通客戶來了,等待服務
6號快速窗口給2號快速客戶服務完,耗時1秒
6號快速窗口正在等待服務
6窗口沒有快速服務,開始取普通服務
6號快速窗口正在等待服務
6號快速窗口開始給4號普通客戶服務
5號VIP窗口給1號vip客戶服務完,耗時2秒
5號VIP窗口正在等待服務
5窗口沒有vip服務,開始取普通服務
5號VIP窗口正在等待服務
5窗口沒有普通服務,休息一秒
3號普通窗口正在等待服務
3窗口沒有普通服務,休息一秒
4號普通窗口正在等待服務
4窗口沒有普通服務,休息一秒
第5號普通客戶來了,等待服務
第3號快速客戶來了,等待服務
5號VIP窗口正在等待服務
5窗口沒有vip服務,開始取普通服務
5號VIP窗口正在等待服務
5號VIP窗口開始給5號普通客戶服務
3號普通窗口正在等待服務
3窗口沒有普通服務,休息一秒
1號普通窗口給1號普通客戶服務完,耗時3秒
1號普通窗口正在等待服務
1窗口沒有普通服務,休息一秒
4號普通窗口正在等待服務
4窗口沒有普通服務,休息一秒
第6號普通客戶來了,等待服務
3號普通窗口正在等待服務
3號普通窗口開始給6號普通客戶服務
1號普通窗口正在等待服務
1窗口沒有普通服務,休息一秒
4號普通窗口正在等待服務
4窗口沒有普通服務,休息一秒
第7號普通客戶來了,等待服務
第4號快速客戶來了,等待服務
第2號vip客戶來了,等待服務
1號普通窗口正在等待服務
1號普通窗口開始給7號普通客戶服務
3號普通窗口給6號普通客戶服務完,耗時1秒
3號普通窗口正在等待服務
3窗口沒有普通服務,休息一秒
4號普通窗口正在等待服務
4窗口沒有普通服務,休息一秒
第8號普通客戶來了,等待服務
3號普通窗口正在等待服務
3號普通窗口開始給8號普通客戶服務
4號普通窗口正在等待服務
4窗口沒有普通服務,休息一秒
第9號普通客戶來了,等待服務
第5號快速客戶來了,等待服務
5號VIP窗口給5號普通客戶服務完,耗時4秒
5號VIP窗口正在等待服務
5號VIP窗口開始給2號vip客戶服務
4號普通窗口正在等待服務
4號普通窗口開始給9號普通客戶服務
第10號普通客戶來了,等待服務

發佈了49 篇原創文章 · 獲贊 12 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章