黑马程序员 银行业务调度系统的分析与理解

----------android培训java培训、java学习型技术博客、期待与您交流!----------

 

银行业务调度系统

需求说明

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

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

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

        • VIP客户:普通客户:快速客户= 163

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

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

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

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

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

面向对象分析与设计

         根据题目要求,是模拟银行的业务调度,那么显然应该有客户和服务窗口ServiceWindow,其实,确切的说客户类型其实就是叫号的类型,客户类型有限,采用枚举则更为合理,在现实当中,我们取钱时,一个大概的过程是,首先取号,等待被叫,根据叫号去对应的窗口。对于不同的客户类型,应该有模拟产生用户的类NumberMachine,该类负责产生各个类型的客户,且该类的实现对象是唯一的,设置成单例比较好,而对于某个窗口,每次服务完之后,都进行判断是否有等待的队列。所以可以设置一个管理叫号的类NumberManager,该类既为用户产生叫号,服务窗口也可以访问该类已获得等待服务的队列,所以该类里应该含有两个线程,他们共享叫号队列。


  • 有三种对应类型的客户:VIP客户,普通客户,快速客户,异步随机生成各种类型的客户,各类型客户在其对应窗口按顺序依次办理业务

      • 每一个客户其实就是由银行的一个取号机器产生号码的方式来表示的。所以,要有一个号码管理器对象,让这个对象不断地产生号码,就等于随机生成了客户。

      • 由于有三类客户,每类客户的号码编排都是完全独立的,本系统一共要产生三个号码管理器对象,各自管理一类用户的排队号码。这三个号码管理器对象统一由一个号码机器进行管理,这个号码机器在整个系统中始终只能有一个,所以,它要被设计成单例。

  • 各类型客户在其对应窗口按顺序依次办理业务,准确地说,应该是窗口依次叫号。

      • 各个窗口怎么知道该叫哪一个号了呢?它一定是问的相应的号码管理器,即服务窗口每次找号码管理器获取当前要被服务的号码

类图

 

编码

 NumberMachine类

 

public class NumberMachine {
	private NumberManager commonManager=new NumberManager();
	private NumberManager expressManager=new NumberManager();
	private NumberManager vipManager=new NumberManager();
   
	//javaBean get(), set()方法
	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();
    //以上为一个单例
}


 

NumberManager类

 

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

/**
 * @author MI_Viewer
 *
 */
public class NumberManager {

	private int lastNumber=1;
	private  List<Integer> queueNumber=new ArrayList<Integer>();
	//synchronized  到多个线程操作它的时候就进入了互斥
	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;
	}
	
	
}


 

 

Servicewindow类

 

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

public class ServiceWindow {

	private  CustomerType type= CustomerType.COMMON;
	private int windowId=1;
	
	//两个Type与windowId的set()方法,跟变量放在一起,便于阅读
	public void setType(CustomerType type) {
		this.type = type;
	}
	public void setWindowId(int windowId) {
		this.windowId = windowId;
	}
	
	
	
	 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() {
				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;
				   long serveTime=new Random().nextInt(maxRand)+1+Constants.MIN_SERVICE_TIME;
				   //取服务的try catch
				   try {
					Thread.sleep(serveTime);
				} catch (InterruptedException e) {
				
					e.printStackTrace();
				}
				   long costTime=System.currentTimeMillis()-beginTime;
				   System.out.println(windowName+"为第"+number+"个"+"普通"+"客户完成服务,耗时 "+costTime/1000+"秒");
				   
      }else{
				   
				   System.out.println(windowName+"没有取到服务任务,先休息1秒钟嘛!" );
				   
				   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 catch
				   try {
					Thread.sleep(Constants.MIN_SERVICE_TIME);
				} catch (InterruptedException e) {
				
					e.printStackTrace();
				}
				   long costTime=System.currentTimeMillis()-beginTime;
				   System.out.println(windowName+"为第"+number+"个"+type+"客户完成服务,耗时 "+costTime/1000+"秒");
				   
      }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;
				   long serveTime=new Random().nextInt(maxRand)+1+Constants.MIN_SERVICE_TIME;
				   //取服务的try catch
				   try {
					Thread.sleep(serveTime);
				} catch (InterruptedException e) {
				
					e.printStackTrace();
				}
				   long costTime=System.currentTimeMillis()-beginTime;
				   System.out.println(windowName+"为第"+number+"个"+type+"客户完成服务,耗时 "+costTime/1000+"秒");
				   
      }else{
				   
				   System.out.println(windowName+"没有取到服务任务!" );
				   //没有取到VIP服务,尝试为普通客户服务
				   commonService();
				   
                }
			}
		 
	 
	
}


Constants类

 

/**
 * @author MI_Viewer
 *
 */
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;
	
}


 

 

CustomerType类

 

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

}


MainClass类

 

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

public class MainClass {
 public static void main(String[]args){
	 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();
	 
	 ServiceWindow vipwindow=new ServiceWindow();
	 vipwindow.setType(CustomerType.VIP);
	 vipwindow.start();
	 
	 //普通客户号生成时间
	 Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
			 new Runnable(){
				 public void run(){
					  Integer number=NumberMachine.getInstance().getCommonManager().generateNewManager();
					 System.out.println("第"+number+"号普通客户等待服务!");
				 }
			 }, 
			 0,
			 //生成概率 普通:快速:VIP  6:3:1
			 Constants.COMMON_CUSTOMER_INTERVAL_TIME, 
			 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
		 );
	 
	 
	 //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
		 );
	 
	 
	 }
}


 

 

总结:commonService、expressService、vipService三个方法还可以进行优化,MainClass里的三种客户号生成可以进行绑定,不过容易形成死锁就先放着了。

 

 

 

 

 

----------android培训java培训、java学习型技术博客、期待与您交流!----------

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
东南亚位于我国倡导推进的“一带一路”海陆交汇地带,作为当今全球发展最为迅速的地区之一,近年来区域内生产总值实现了显著且稳定的增长。根据东盟主要经济体公布的最新数据,印度尼西亚2023年国内生产总值(GDP)增长5.05%;越南2023年经济增长5.05%;马来西亚2023年经济增速为3.7%;泰国2023年经济增长1.9%;新加坡2023年经济增长1.1%;柬埔寨2023年经济增速预计为5.6%。 东盟国家在“一带一路”沿线国家中的总体GDP经济规模、贸易总额与国外直接投资均为最大,因此有着举足轻重的地位和作用。当前,东盟与中国已互相成为双方最大的交易伙伴。中国-东盟贸易总额已从2013年的443亿元增长至 2023年合计超逾6.4万亿元,占中国外贸总值的15.4%。在过去20余年中,东盟国家不断在全球多变的格局里面临挑战并寻求机遇。2023东盟国家主要经济体受到国内消费、国外投资、货币政策、旅游业复苏、和大宗商品出口价企稳等方面的提振,经济显现出稳步增长态势和强韧性的潜能。 本调研报告旨在深度挖掘东南亚市场的增长潜力与发展机会,分析东南亚市场竞争态势、销售模式、客户偏好、整体市场营商环境,为国内企业出海开展业务提供客观参考意见。 本文核心内容: 市场空间:全球行业市场空间、东南亚市场发展空间。 竞争态势:全球份额,东南亚市场企业份额。 销售模式:东南亚市场销售模式、本地代理商 客户情况:东南亚本地客户及偏好分析 营商环境:东南亚营商环境分析 本文纳入的企业包括国外及印尼本土企业,以及相关上下游企业等,部分名单 QYResearch是全球知名的大型咨询公司,行业涵盖各高科技行业产业链细分市场,横跨如半导体产业链(半导体设备及零部件、半导体材料、集成电路、制造、封测、分立器件、传感器、光电器件)、光伏产业链(设备、硅料/硅片、电池片、组件、辅料支架、逆变器、电站终端)、新能源汽车产业链(动力电池及材料、电驱电控、汽车半导体/电子、整车、充电桩)、通信产业链(通信系统设备、终端设备、电子元器件、射频前端、光模块、4G/5G/6G、宽带、IoT、数字经济、AI)、先进材料产业链(金属材料、高分子材料、陶瓷材料、纳米材料等)、机械制造产业链(数控机床、工程机械、电气机械、3C自动化、工业机器人、激光、工控、无人机)、食品药品、医疗器械、农业等。邮箱:market@qyresearch.com

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值