黑马程序员之银行业务调度系统

------- android培训java培训、期待与您交流! ----------

银行业务调度系统的总结
1,对象有客户、号码、业务窗口
2,客户是根据号码来区分的,一个客户对应一个号码。号码有贵宾、普通和快速三种区分。所以要产生三个号码管理器对象,各自管理一类用户的排队号码。这三个号码管理器对象统一由一个号码机器进行管理,这个号码机器在整个系统中始终只能有一个,所以,它要被设计成单例
3,业务窗口也是根据号码的三种区分,进行不同的服务。窗口分贵宾、普通和快速三种。不同的窗口分别为不同的客户服务。所以服务窗口类需要有窗口类别的属性,另外要有窗口的名称的属性。
4,业务窗口服务不断获取客户号码,一旦有客户等待,就获取到号码进行服务。
5,在主程序中,建立窗口的实例对象,调用start方法,启动线程服务,并产生客户。
6,整个系统就是由6个线程交替执行,即贵宾(1个)、普通(4个)和快速(1个)。
7,系统用到枚举类,如果想要输出自定义的信息,需要覆盖toString方法。
8,用到一个存放常量的类。编程过程中,使用到的常量最好统一进行定义为一个类中的静态常量。
根据"谁拥有数据,谁提供处理数据的方法"的原则进行分析
   客户拥有贵宾、普通、快速三种特性,所以客户应该提供生成三种客户的方法。但是客户其实是跟号码一一对应的,银行是根据号码来确定有没有客户的。所以提供生成三种客户方法的对象应该是号码。
   号码还要提供获取下一个要服务的对象的方法和产生新号码的方法。
   窗口拥有窗口ID、窗口类别(贵宾、普通和快速)的属性,还要有为客户服务的方法。
程序处理流程
   1,main方法中,创建三种类型服务窗口的对象,并调用对象的start方法,启动线程。
   2,每个对象启动一个线程。线程中根据对象的类别(Type)不同,进行不同的服务(commonServie,vipService,expressService)。
   3,普通客户服务(commonService)流程:
      首先利用号码机获得普通客户的实例对象,然后调用号码管理类的fetchServiceNumber方法获取一个普通客户队列等待服务的号码。如果号码不为空,则开始服务,否则等待。
   4,快速客户服务(expressService)流程:
      首先利用号码机获得快速客户的实例对象,然后调用号码管理类的fetchServiceNumber方法获取一个快速客户队列等待服务的号码。如果号码不为空,则开始服务,否则进行普通客户服务。
   5,VIP客户服务(vipService)流程:
      首先利用号码机获得VIP客户的实例对象,然后调用号码管理类的fetchServiceNumber方法获取一个VIP客户队列等待服务的号码。如果号码不为空,则开始服务,否则进行普通客户服务。

源代码:

号码管理类:

package bank;

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(){
		Integer number = null;
		//队列有值才取号,否则报错
		if(queueNumber.size()>0){
			number = queueNumber.remove(0);
		}
		//取走集合中的值,这个方法有一个返回值,返回值就是取走的值
		return number;
	}
	
}

 

号码机:
 

package bank;



public class NumberMachine {
	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;
	}
	//单例模式构造方法私有化
	private NumberMachine(){

	}
	public static NumberMachine getInstance(){
		return instance;
	}
	private static NumberMachine instance = new NumberMachine();
}

 

业务窗口:
 

package bank;

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

public class ServiceWindow {
	//使用set和get方法设置属性值,比较灵活;如果使用构造方法生成时赋值,那么不能进行改动
	public void setType(CustomerType type) {
		this.type = type;
	}

	public void setWindowId(int windowId) {
		this.windowId = windowId;
	}

	//默认是普通窗口
	private CustomerType type = CustomerType.COMMON;
	private int windowId = 1;
	
	public void start(){
		//线程池执行任务,线程池在到池里去找一个空闲的线程去执行
		Executors.newSingleThreadExecutor().execute(new Runnable(){

			public void run() {
				while(true){	
				//switch效率比if else高,switch的数据类型不能是long
					switch(type){
					case COMMON:
						commonService();
						break;
					case VIP:
						vipService();
						break;
					case EXPRESS:
						expressService();
						break;
					}
//					NumberMachine.getInstance();
					
				}
			}

		});

	}
	private void commonService() {
		String windowName = "第"+windowId+"号"+type+"窗口";
		Integer number = NumberMachine.getInstance().getCommonManager().fetchServiceNumber();
		System.out.println(windowName+"正在获取需要服务的号码");
		if(number!=null){
			System.out.println(windowName+"为第"+number+"个"+"普通"+"客户服务");
			//开始服务的时间
			long beginTime = System.currentTimeMillis();
			//最大的服务时间
			int maxRand = Constants.MAX_SERVICE_TIME-Constants.MIN_SERVICE_TIME;
			//随机的服务时间,产生的随机数位0到8999之间的随机数,希望产生1-9000,所以再加1
			long serviceTime=new Random().nextInt(maxRand)+1+Constants.MIN_SERVICE_TIME;
			try {
				Thread.sleep(serviceTime);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			//服务结束的时间
			long endTime = System.currentTimeMillis();
			//服务耗时
			long costTime = endTime-beginTime;
			System.out.println(windowName+"为第"+number+"个"+type+"客户完成服务,同时消耗时间为"+costTime);
		}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().fetchServiceNumber();
		System.out.println(windowName+"正在获取需要服务的号码");
		if(number!=null){
			System.out.println(windowName+"为第"+number+"个"+type+"客户服务");
			long beginTime = System.currentTimeMillis();
			try {
				Thread.sleep(Constants.MIN_SERVICE_TIME);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			long endTime = System.currentTimeMillis();
			long costTime = endTime-beginTime;
			System.out.println(windowName+"为第"+number+"个"+type+"客户完成服务,同时消耗时间为"+costTime);
		}else{
			System.out.println(windowName+"没有需要服务的号码,先休息一秒");
			commonService();
		}
	}
	//VIP服务
	private void vipService() {
		String windowName = "第"+windowId+"号"+type+"窗口";
		Integer number = NumberMachine.getInstance().getVipManager().fetchServiceNumber();
		System.out.println(windowName+"正在获取需要服务的号码");
		if(number!=null){
			System.out.println(windowName+"为第"+number+"个"+type+"客户服务");
			long beginTime = System.currentTimeMillis();
			//最大的服务时间
			int maxRand = Constants.MAX_SERVICE_TIME-Constants.MIN_SERVICE_TIME;
			//随机的服务时间,产生的随机数位0到8999之间的随机数,希望产生1-9000,所以再加1
			long serviceTime=new Random().nextInt(maxRand)+1+Constants.MIN_SERVICE_TIME;
			try {
				Thread.sleep(serviceTime);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			long endTime = System.currentTimeMillis();
			long costTime = endTime-beginTime;
			System.out.println(windowName+"为第"+number+"个"+type+"客户完成服务,同时消耗时间为"+costTime);
		}else{
			System.out.println(windowName+"没有需要服务的号码,开始获取普通用户");
			commonService();
		}
	}
}

 

客户类型,即号码类型:使用枚举
 

package bank;

public enum CustomerType {
	COMMON,VIP,EXPRESS;
	//type
	public String toString(){
		switch(this){
		case COMMON:
			return "普通";
		case VIP:
			return "贵宾";
		case EXPRESS:
			return "快速";
		}
		return null;
	}
	
	
}


 常量类:最大服务时间,最小服务时间,客户进来的频率

 

package bank;

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

 

主程序:
 

package bank;

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

public class mainClass {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		//4个普通窗口
		for(int i = 1;i<5;i++){
			ServiceWindow commonWindow = new ServiceWindow();
			commonWindow.setWindowId(i);
			commonWindow.start();
		}
		//贵宾窗口
		ServiceWindow vipWindow = new ServiceWindow();
		vipWindow.setType(CustomerType.VIP);
		vipWindow.start();
		//快速窗口
		ServiceWindow expressWindow = new ServiceWindow();
		expressWindow.setType(CustomerType.EXPRESS);
		expressWindow.start();

		//COMMON调度线程池,一秒钟增加一个普通客户
		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
			);
		//EXPRESS
		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
			);
		
	}

}



 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值