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

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

 

先上需求:

 

 

银行业务调度系统

 

模拟实现银行业务调度系统逻辑,具体需求如下:

 

       银行内有6个业务窗口,1- 4号窗口为普通窗口,5号窗口为快速窗口,6号窗口为VIP窗口。

 

       有三种对应类型的客户:VIP客户,普通客户,快速客户(办理如交水电费、电话费之类业务的客户)。

 

       异步随机生成各种类型的客户,生成各类型用户的概率比例为:

 

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

 

        客户办理业务所需时间有最大值和最小值,在该范围内随机设定每个VIP客户以及普通客户办理业务所需的时间,快速客户办理业务所需时间为最小值(提示:办理业务的过程可通过线程Sleep的方式模拟)。

 

        各类型客户在其对应窗口按顺序依次办理业务。

 

        当VIP(6号)窗口和快速业务(5号)窗口没有客户等待办理业务的时候,这两个窗口可以处理普通客户的业务,而一旦有对应的客户等待办理业务的时候,则优先处理对应客户的业务。

 

        随机生成客户时间间隔以及业务办理时间最大值和最小值自定,可以设置。

 

        不要求实现GUI,只考虑系统逻辑实现,可通过Log方式展现程序运行结果。

 

--------------------------------------------------------------------------------------------------------------

 

分析:

         客户进入银行先分类型取票排队,然后等待服务窗口叫号。所以我觉得计数器应该拥有客户排队的数据,那么编号就当作是一个个客户,计数器就拥有对外访问客户的方法,而窗口就向计数器询问有没有下一个客户,如果没有就换普通类型再询问有没有,如果始终没有下一个客户,那么就休息一下再继续

        快速窗口和vip窗口在没有对应客户的情况下还要为普通客户服务。所以窗口类中应该有判断类型的方法

        由于服务的时间有最大值和最小值,为了体现面向对象的思想,就将时间封装成一个类。

 

下面就进行代码的分析,自己没有照着老师教的抄,而是以自己的思想做一遍,体会其中的差距,理解老师每一步为什么要那么做。

最后总结分析出自己虽然也能将代码做出来,但没有将任何事物看作对象来对待,面向对象的体会也许就只能在实际的项目经验中去积累。

窗口类型:

/**
 * 由于窗口类型是不变的,分别对应 普通 快速 VIP
 * @author 不信
 *
 */
public enum windowType {
	COMMON,FAST,VIP;
	
	//覆盖父类的toString()
	public String toString()
	{
		switch (this) {
		case COMMON:
			return "普通";
		case FAST:
			return "快速";
		default:
			return name();
		}
	}
	
	//用户类型对应服务时间,其中快速客户为最小值也就是1秒
	public int useTime()
	{
		if(this != FAST)
			return Constants.MAX_SERVICE_TIME;
		else {
			return Constants.MIN_SERVICE_TIME;
		}
	}
}

 

服务时间的最大值和最小值:

/**
 * 服务时间的最小值与最大值
 * @author 不信
 *
 */
public class Constants {
	public static int MAX_SERVICE_TIME = 10; //10秒!
	public static int MIN_SERVICE_TIME = 1; //1秒!
}



计数器,里面包含了客户的排队顺序

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

/**
 * 这是一个计数器类,由于顾客领了票就说明排了队,所以计数器拥有顾客
 * 服务窗口可以问计数器有没有顾客
 * 
 * */
public class counter {
	
	//顾客排队的号
	private int num = 1;
	
	//顾客类型不一样,办理业务所用的时间也就不一样
	private int time;
	
	//顾客类型
	private windowType type;
	
	//存储顾客排队的号
	private LinkedList<Integer> list = new LinkedList<Integer>();
	
	
	//计数器类是一开始就有类型与办理业务所需的最大时间
	public counter(int time,windowType type)
	{
		this.time = time;
		this.type = type;
		addList();
	}
	
	//定时进入一位顾客,由于顾客类型的不一样,光临的时间也不一样
	public synchronized void addList()
	{
		Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
				new Runnable() {
					
					@Override
					public void run() {
						list.addLast(num++);
					}
				},
				0,
				time,
				TimeUnit.SECONDS
				);
		System.out.println("第"+num+"位"+type.toString()+"客户等待服务");
	}
	
	//服务窗口调用这个方法来获取正在排队的客户,如果没有返回null
	public synchronized Integer take()
	{
		if(!list.isEmpty())
			return list.removeFirst();
		else {
			return null;
		}
	}
		
}


三种窗口类型对应了三种客户类型

/**
 * 三种客户类型的对象,提供对外访问的静态方法,服务窗口其实就是根据类型来访问的
 * @author 不信
 *
 */
public class client {
	private static counter COMMONCLIENT = new counter(1, windowType.COMMON);
	private static counter FASTCLIENT = new counter(3,windowType.FAST);
	private static counter VIPCLIENT = new counter(6, windowType.VIP);
	
	private client(){}
	
	public static counter getClient(windowType type)
	{
		switch (type) {
		case COMMON:
			return COMMONCLIENT;
		case FAST:
			return FASTCLIENT;
		default:
			return VIPCLIENT;
		}
	}
	


 

服务窗口

import java.util.Random;
import java.util.concurrent.Executors;
/**
 * 服务窗口类
 * @author 不信
 *
 */
public class window {
	
	//每个窗口都有自己对应的类型
	private windowType type;
	
	//每个窗口都有自己的编号
	private int num;
	
	//在初始化时,就有了类型和编号
	public window(windowType type, int num)
	{
		this.type = type;
		this.num = num;
	}
	
	//窗口开始工作
	public void windower()
	{
		System.out.println("第"+num+"号"+this.type+"窗口开始服务");
		
		//创建一个线程池,其中只有一个线程
		Executors.newSingleThreadExecutor().execute(new Runnable() {
			
			@Override
			public void run() {
				while(true)
				{
					System.out.println("第"+num+"号"+window.this.type+"窗口正在等待客户");
					
					//调用窗口的工作内容
					work(type);
				}
			}
		});
	}
	
	//窗口工作的内容
	public void work(windowType type)
	{
		//窗口寻找对应类型的客户是否存在,如果存在就给予服务,如果不存在就执行 else if()
		Integer i = client.getClient(type).take();
		if(i!=null){
			System.out.println("第"+num+"号"+this.type+"窗口正在为第"+i+"位"
					+type+"客户服务");
			
			//以客户的类型计算出要给服务的时间
			int randomTime = new Random().nextInt(type.useTime())+1;
			try {
				//这里以线程 sleep()的形式模仿
				Thread.sleep(randomTime*1000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
			//当线程“醒”来时,就给对应得客户服务完毕
			System.out.println("第"+num+"号"+this.type+"窗口为第"+i+"位"
					+type+"客户服务耗时"+randomTime+"秒");
		}
		
		//由于vip窗口和快速窗口在没有对应客户存在的情况下,还要给普通客户服务所以这里使用了递归
		else if(type != windowType.COMMON)
		{
			work(windowType.COMMON);	
		}
		else{
			
			//如果始终没有需要服务的客户,就sleep()休息一秒,醒来继续查找
			System.out.println("第"+num+"号"+this.type+"窗口没有取到任务,正在休息一秒");
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
	
}


最后主函数调用:

public class MainClass {
	public static void main(String[] args)
	{
		
		//四个普通窗口
		for(int i = 1;i < 5;i++)
		{
			new window(windowType.COMMON, i).windower();
		}
		
		//一个快速窗口 和一个VIP窗口
		new window(windowType.FAST, 5).windower();
		new window(windowType.VIP, 6).windower();
	}
}
 
 

运行结果如图

 

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

                                                              详情请点击:http://edu.csdn.net/

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值