——银行业务调度系统

---------------------- ASP.Net+Unity开发.Net培训、期待与您交流! ----------------------

银行业务调度系统

需求:

   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);
	}

}


你可能感兴趣的:(基础技术博客,java基础技术博客)