java实例

        这一篇主要说一下两个程序示例,这两道题对于我们所学知识的综合利用有很大的帮助,对于很多知识点我们大多都是处于一知半解的状态,知道有这么回事,但是真正的开发利用中就是不知道如何下手,还有一些知识点是没有接触过,通过这两道题把所学的知识点串一下,更重要的是培养一种灵活运用所学知识的能力和学习的态度与方法。


一.交通灯管理系统


1.交通灯管理系统的要求

这个交通灯管理系统要求异步随机生成按照各个路线行驶的车辆。

例如:

       由南向而来去往北向的车辆---- 直行车辆

       由西向而来去往南向的车辆 ---- 右转车辆

       由东向而来去往南向的车辆 ---- 左转车辆

       。。。。。。

        ①   信号灯忽略黄灯,只考虑红灯和绿灯。

        ②   应考虑左转车辆控制信号灯,右转车辆不受信号灯控制。

        ③   具体信号灯控制逻辑与现实生活中普通交通灯控制逻辑相同,不考虑特殊情况下的控制逻辑。

        注:南北向车辆与东西向车辆交替放行,同方向等待车辆应先放行直行车辆而后放行左转车辆。

        ④   每辆车通过路口时间为1秒(提示:可通过线程Sleep的方式模拟)。

        随机生成车辆时间间隔以及红绿灯交换时间间隔自定,可以设置。

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

2.系统分析

      我们按照要求并联想现实生活中的实际路口来思考,凭借大多数人的大脑是无法在脑海中构建这个交通灯的全部情况,所以我们要通过画图来说明:



        通过这张示意图我们可以看出来总共有12条路线,为了统一编程模型,可以假设每条路线都有一个红绿灯对其进行控制,右转弯的4条路线的控制灯可以假设称为常绿状态,另外,其他的8条线路是两两成对的(方向相反),可以归为4组,所以,程序只需考虑图中标注了数字号的4条路线的控制灯的切换顺序,这4条路线其所对应的相反方向的路线的控制灯跟随这4条路线切换,不必额外考虑。

        也就是说第一条路线是由南向北行驶,我们用S2N表示,与他是一组的是N2S,因为他们虽然方向不同,但是可以被同状态的红绿灯控制,第二条线路是S2W,与他相对的是N2E,依次分析这个交通灯管理系统中总共有4条线路被红绿灯控制。

        根据我们现实中的情况当①线路绿灯后,S2N和N2S方向上的车启动,当①红灯后,②线路绿灯,然后③线路,最后④线路,④线路红灯之后①线路接着绿灯。

3.面相对象的需求与分析

        根据需求我们来分析一下本系统中需要用到哪些对象,红绿灯控制系统,首先要有车,然后车得用灯控制,车还得有行进的路线,汽车看到自己所在路线对应的灯绿了就能穿过路口吗?不是,还需要看其前面是否有车,看前面是否有车,就需要一个新的对象——路,路中存储着车辆的集合,显然路上就应该有增加车辆和减少车辆的方法了。再看题目,我们这里并不要体现车辆移动的过程,只是捕捉出车辆穿过路口的过程,也就是捕捉路上减少一辆车的过程,所以,这个车并不需要单独设计成为一个对象,用一个字符串表示就可以了。

每条路线上都会出现多辆车,路线上要随机增加新的车,在灯绿期间还要每秒减少一辆车。

(1)设计一个Road类来表示路线,每个Road对象代表一条路线,总共有12条路线,即系统中总共要产生12个Road实例对象。

        1>每条路线上随机增加新的车辆,增加到一个集合中保存。

        2>每条路线每隔一秒都会检查控制本路线的灯是否为绿,是则将本路线保存车的集合中的第一辆车移除,即表示车穿过了路口。

        3>每条路线每隔一秒都会检查控制本路线的灯是否为绿,一个灯由绿变红时,应该将下一个方向的灯变绿。

代码如下:

public class Road {
	//建立集合用来存储车(字符串)
	private List<String> vechicles = new ArrayList<String>();
	
	//每条路线都有着自己的名字,我们通过构造函数接收他的名字
	private String name =null;
	
	//在一个Road对象实例化的过程中开启一条线程来产生车辆
	public Road(String name){
		this.name = name;
		
		/*模拟车辆不断随机上路的过程
		 * 利用线程池来创建新的线程,在新的线程中添加车辆
		 * */		
		ExecutorService pool = Executors.newSingleThreadExecutor();
		pool.execute(new Runnable(){
			public void run(){
				//每条路上产生49辆车
				for(int i=1;i<50;i++){
					//随机暂停几秒后此道路添加车辆
					try {					
						Thread.sleep((new Random().nextInt(10) + 1) * 1000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					//内部类访问外部类的成员变量,可以加this,但因为局部变量名也为name,所以使用下面格式
					vechicles.add(Road.this.name + "_" + i);
				}				
			}			
		});
		
		/*每隔一秒检查对应的灯是否为绿,是则放行一辆车
		 * 利用调度池来构建一个定时器,每隔1秒来检测这条线对应的灯
		 * */		
		ScheduledExecutorService timer =  Executors.newScheduledThreadPool(1);
		timer.scheduleAtFixedRate(
				//定时器要做的事情封装进Runnable当中
				new Runnable(){
					public void run(){
						//如果集合内有车,那么判断灯的状态
						if(vechicles.size()>0){
							boolean lighted = Lamp.valueOf(Road.this.name).isLighted();
							if(lighted){
								//集合在删除元素时会把该元素返回来
								System.out.println(vechicles.remove(0) + "  号车通过路口!");
							}
						}
						
					}
				},
				1,//过多少时间量之后去做Runnable封装的事情
				1,//做完Runnable封装的事情之后再过多少时间量重新去做
				TimeUnit.SECONDS);//单位为秒
		
	}
}

(2)设计一个Lamp类来表示一个交通灯,每个交通灯都维护一个状态:亮(绿)或不亮(红),每个交通灯要有变亮和变黑的方法,并且能返回自己的亮黑状态。

        1>总共有12条路线,所以,系统中总共要产生12个交通灯。右拐弯的路线本来不受灯的控制,但是为了让程序采用统一的处理方式,故假设出有四个右拐弯的灯,只是这些灯为常亮状态,即永远不变黑。

        2>除了右拐弯方向的其他8条路线的灯,它们是两两成对的,可以归为4组,所以,在编程处理时,只要从这4组中各取出一个灯,对这4个灯依次轮询变亮,与这4个灯方向对应的灯则随之一同变化,因此Lamp类中要有一个变量来记住自己相反方向的灯,在一个Lamp对象的变亮和变黑方法中,将对应方向的灯也变亮和变黑。每个灯变黑时,都伴随者下一个灯的变亮,Lamp类中还用一个变量来记住自己的下一个灯,除去这两个变量之外,还要有一个变量记录自己的状态。

        注意:无论在程序的什么地方去获得某个方向的灯时,每次获得的都是同一个实例对象,所以Lamp类改用枚举来做显然具有很大的方便性,永远都只有代表12个方向的灯的实例对象。

首先设计Lamp类来描述灯:

/*
 * 每个Lamp元素代表一个方向上的灯,总共有12个方向,所有总共有12个Lamp元素。
 * 有如下一些方向上的灯,每两个形成一组,一组灯同时变绿或变红,所以,
 * 程序代码只需要控制每组灯中的一个灯即可:
 * s2n,n2s    
 * s2w,n2e
 * e2w,w2e
 * e2s,w2n
 * s2e,n2w
 * e2n,w2s
 * 上面最后两行的灯是虚拟的,由于从南向东和从西向北、以及它们的对应方向不受红绿灯的控制,
 * 所以,可以假想它们总是绿灯。
 */

public enum Lamp {
	/*每个枚举元素各表示一个方向的控制灯,每一个枚举元素在初始化的时候要接收3个参数
	 * 1.相反方向的灯2.下一个要点亮的灯3.灯的状态*/	
	S2N("N2S","S2W",false),S2W("N2E","E2W",false),E2W("W2E","E2S",false),E2S("W2N","S2N",false),
	/*下面元素表示与上面的元素的相反方向的灯,它们的“相反方向灯”和“下一个灯”应忽略不计!*/
	N2S(null,null,false),N2E(null,null,false),W2E(null,null,false),W2N(null,null,false),
	/*由南向东和由西向北等右拐弯的灯不受红绿灯的控制,所以,可以假想它们总是绿灯*/
	S2E(null,null,true),E2N(null,null,true),N2W(null,null,true),W2S(null,null,true);
	
	//使用传递字符串的方式来获得灯的名字
	private Lamp(String opposite,String next,boolean lighted){
		this.opposite = opposite;
		this.next = next;
		this.lighted = lighted;
	}


	/*当前灯的状态*/	
	private boolean lighted;
	/*与当前灯同时为绿的对应方向*/	
	private String opposite;
	/*当前灯变红时下一个变绿的灯*/	
	private String next;
	//对外提供方法获取灯的状态
	public boolean isLighted(){
		return lighted;
	}
	
	/**
	 * 某个灯变绿时,它对应方向的灯也要变绿
	 */	
	public void light(){
		this.lighted = true;
		if(opposite != null){
			//valueOf方法可以通过字符串获取到其对应的对象
			Lamp.valueOf(opposite).light();
		}
		System.out.println(name() + " 灯变绿了,下面总共应该有6个方向能看到汽车穿过!");
		
	}
	
	/**
	 * 某个灯变红时,对应方向的灯也要变红,并且下一个方向的灯要变绿
	 * @return 下一个要变绿的灯
	 */	
	public Lamp blackOut(){
		//当前灯变红
		this.lighted = false;
		//对应的灯也变红
		if(opposite != null){
			Lamp.valueOf(opposite).blackOut();
		}		
		//下一个灯变绿
		Lamp nextLamp= null;
		if(next != null){
			nextLamp = Lamp.valueOf(next);
			System.out.println("绿灯从" + name() + "-------->切换为" + next);			
			nextLamp.light();
		}
		return nextLamp;
	}
}

设计一个LampController类,用来管理灯对象,它定时让当前的绿灯变红。

/*
 * 定义灯的控制器,在Lamp中只是定义了灯的属性和方法,而如何控制灯
 * 则由灯控制器来操作
 * */
public class LampController {
	//首先要定义成员变量表征当前的灯
	private Lamp currentLamp;
	
	//定义控制灯的方法
	public LampController(){
		//获取由南向北的灯
		currentLamp = Lamp.S2N;
		//S2N变绿,这样绿的是两个灯,北到南也绿了	
		currentLamp.light();
		
		/*每隔10秒将当前绿灯变为红灯,并让下一个方向的灯变绿
		 * 使用定时器
		 * */		 
		ScheduledExecutorService timer = Executors.newScheduledThreadPool(1);
		timer.scheduleAtFixedRate(
				new Runnable(){
					public void run()
					{
						//把当前灯变黑,blackOut方法把下一个灯也变绿了
						currentLamp = currentLamp.blackOut();
					}
				},
				10,
				10, 
				TimeUnit.SECONDS);
		
	}
}

我们所有的对象都已经创建好了,现在我们创建主线程:

public class MainClass {

	public static void main(String[] args) {
		
		/*产生12个方向的路线,一个个new太麻烦交给for循环去做*/		
		String [] directions = new String[]{
				"S2N","S2W","E2W","E2S","N2S","N2E","W2E","W2N","S2E","E2N","N2W","W2S"		
		};
		for(int i=0;i<directions.length;i++){
			new Road(directions[i]);
		}
		
		/*产生整个交通灯系统*/		
		new LampController();
	}
}

运行主线程,就可以得到运行结果:

N2S 灯变绿了,下面总共应该有6个方向能看到汽车穿过!

S2N 灯变绿了,下面总共应该有6个方向能看到汽车穿过!

N2S_1  号车通过路口!

W2S_1  号车通过路口!

W2S_2  号车通过路口!

W2S_3  号车通过路口!

N2S_2  号车通过路口!

W2S_4  号车通过路口!

S2N_1  号车通过路口!

S2E_1  号车通过路口!

E2N_1  号车通过路口!

N2W_1  号车通过路口!

E2N_2  号车通过路口!

绿灯从S2N-------->切换为S2W

N2E 灯变绿了,下面总共应该有6个方向能看到汽车穿过!

S2W 灯变绿了,下面总共应该有6个方向能看到汽车穿过!

S2W_1  号车通过路口!

N2E_1  号车通过路口!

S2W_2  号车通过路口!

N2E_2  号车通过路口!

N2W_2  号车通过路口!

S2E_3  号车通过路口!

W2S_5  号车通过路口!

S2W_4  号车通过路口!

S2E_4  号车通过路口!

N2W_3  号车通过路口!

N2E_4  号车通过路口!

E2N_3  号车通过路口!

。。。。。。

由于是随机的,所以每次运行结果是不一致的,但是运行的状态就是这个样子。结果是我们一步一步做出来的,总结一下,这个红绿灯控制系统中我们使12条路线对应12个红绿灯,统一了系统模型,而每一个灯在系统中的对象都是唯一的,使用枚举,我们又通过分析发现只要控制4条路线就可以让这个交通灯系统运行,简化了代码的书写。通过这个示例我觉得我们在编程的时候首先要明确需求,通过需求来分析要使用哪些对象,然后去构建对象和使用对象。


二.银行业务调度系统


1.银行业务调度系统的要求

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

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

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

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

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

        客户办理业务所需时间有最大值和最小值,在该范围内随机设定每个VIP客户以及普通客户办理业务所需的时间,快速客户办理业务所需时间为最小值

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

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

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

2.面向对象的分析和设计

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

(1)首先,我们应该明确银行用来确定客户是通过一个取号机器来明确的,所以我们就想到需要有一个号码管理器对象,由于有三类客户,每类客户的号码编排都是完全独立的,所以,我想到本系统一共要产生三个号码管理器对象,各自管理一类用户的排队号码。这三个号码管理器对象统一由一个号码机器进行管理,这个号码机器在整个系统中始终只能有一个,所以,它要被设计成单例。

(2)各类型客户在其对应窗口按顺序依次办理业务 ,准确地说,应该是窗口依次叫号。各个窗口怎么知道该叫哪一个号了呢?它一定是问的相应的号码管理器,即服务窗口每次找号码管理器获取当前要被服务的号码。

我们通过示意图来了解一下这个系统的构成:




 

我们来看一下代码的设计:定义号码管理器类:

/*
 * 定义号码管理器类,这个类中有产生新号码的方法和反馈给窗口号码的方法
 * 注意点:
 * 1. 由于产生的新号码并不是马上就被窗口获取到,所以每产生一个号码都需要存储
 * 起来等待窗口的调度,在此我们使用集合来存储产生的号码
 * 2.产生新号码和获取号码是不同的线程,多线程访问公有资源要加锁。
 * */
public class NumberManager {
	private int lastNumber = 0;
	private List queueNumbers = new ArrayList();
	
	//产生新的号码
	public synchronized Integer generateNewNumber(){
		queueNumbers.add(++lastNumber);
		return lastNumber;
	}
	//定义取得方法
	public synchronized Integer fetchNumber(){
		if(queueNumbers.size()>0){
			return (Integer)queueNumbers.remove(0);
		}else{
			return null;
		}
	}
}

然后设计取号器:

/*
 * 定义取号器类,这个类可以生成3个号码管理器对象
 * 由于取号器在银行系统中只有一个所以要设计成单例设计模式
 * */
public class NumberMachine {
	
	//私有本类构造函数,不能new对象
	private NumberMachine(){}
	//new一个本类对象以保证此类对象的唯一性
	private static NumberMachine instance = new NumberMachine();
	//对外提供方法将本类对象返回
	public static NumberMachine getInstance(){
		return instance;
	}
	
	
	//定义三个成员变量分别对应3个号码管理器对象
	private NumberManager commonManager = new NumberManager();//普通客户
	private NumberManager expressManager = new NumberManager();//快速客户
	private NumberManager vipManager = new NumberManager();//VIP客户
	public NumberManager getCommonManager() {
		return commonManager;
	}
	public NumberManager getExpressManager() {
		return expressManager;
	}
	public NumberManager getVipManager() {
		return vipManager;
	}
	
}

设计窗口:

public class ServiceWindow {
	
	
	private static Logger logger = Logger.getLogger("cn.itcast.bankqueue");
	private CustomerType type = CustomerType.COMMON;
	private int number = 1;

	public CustomerType getType() {
		return type;
	}

	public void setType(CustomerType type) {
		this.type = type;
	}
	
	public void setNumber(int number){
		this.number = number;
	}
	
	//定义方法开启一条线程,这条线程执行取号的动作
	public void start(){
		Executors.newSingleThreadExecutor().execute(
				new Runnable(){
					public void run(){
						//下面这种写法的运行效率低,最好是把while放在case下面
						while(true){
							switch(type){
								case COMMON:
									commonService();
									break;
								case EXPRESS:
									expressService();
									break;
								case VIP:
									vipService();
									break;
							}
						}
					}
				}
		);
	}
	//为普通客户服务
	private void commonService(){
		String windowName = "第" + number + "号" + type + "窗口";		
		System.out.println(windowName + "开始获取普通任务!");
		//获取到普通客户所对应的号码管理器中的等待号
		Integer serviceNumber = NumberMachine.getInstance().getCommonManager().fetchNumber();		
		if(serviceNumber != null ){
			System.out.println(windowName + "开始为第" + serviceNumber + "号普通客户服务");	
			//在外部定义了常量类提供最大服务时间和最小时间
			int maxRandom = Constants.MAX_SERVICE_TIME - Constants.MIN_SERVICE_TIME;
			//模拟客户的服务时间,利用Random随机生成最大值10秒和最小值1秒之间的任意秒
			int serviceTime = new Random().nextInt(maxRandom)+1 + Constants.MIN_SERVICE_TIME;
	
			try {
				Thread.sleep(serviceTime);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			//当线程sleep之后醒来打印这个时间
			System.out.println(windowName + "完成为第" + serviceNumber + "号普通客户服务,总共耗时" + serviceTime/1000 + "秒");		
		}else{
			System.out.println(windowName + "没有取到普通任务,正在空闲一秒");		
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}				
		}
	}
	//为快速客户服务
	private void expressService(){
		//获取快速客户号码管理器反馈的号码
		Integer serviceNumber = NumberMachine.getInstance().getExpressManager().fetchNumber();
		String windowName = "第" + number + "号" + type + "窗口";	
		System.out.println(windowName + "开始获取快速任务!");		
		if(serviceNumber !=null){
			System.out.println(windowName + "开始为第" + serviceNumber + "号快速客户服务");
			//服务时间就是最小值1秒
			int serviceTime = Constants.MIN_SERVICE_TIME;
			try {
				Thread.sleep(serviceTime);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}		
			System.out.println(windowName + "完成为第" + serviceNumber + "号快速客户服务,总共耗时" + serviceTime/1000 + "秒");		
		}else{
			//当没有获取到快速客户时切换为普通客户
			System.out.println(windowName + "没有取到快速任务!");				
			commonService();
		}
	}
	
	private void vipService(){
		//获取VIP客户的号码管理器反馈的号码
		Integer serviceNumber = NumberMachine.getInstance().getVipManager().fetchNumber();
		String windowName = "第" + number + "号" + type + "窗口";	
		System.out.println(windowName + "开始获取VIP任务!");			
		if(serviceNumber !=null){
			System.out.println(windowName + "开始为第" + serviceNumber + "号VIP客户服务");
			
			int maxRandom = Constants.MAX_SERVICE_TIME - Constants.MIN_SERVICE_TIME;
			int serviceTime = new Random().nextInt(maxRandom)+1 + Constants.MIN_SERVICE_TIME;
			try {
				Thread.sleep(serviceTime);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}		
			System.out.println(windowName + "完成为第" + serviceNumber + "号VIP客户服务,总共耗时" + serviceTime/1000 + "秒");		
		}else{
			//当没有获取到VIP客户时切换为普通客户
			System.out.println(windowName + "没有取到VIP任务!");				
			commonService();
		}	
	}
}

在窗口的设计中我们使用到了一个枚举来获取三种类型的窗口:

public enum CustomerType {
	COMMON,EXPRESS,VIP;
	
	//根据定义的枚举对象名返回相应的中文表现形式
	public String toString(){
		String name = null;
		switch(this){
		case COMMON:
			name = "普通";
			break;
		case EXPRESS:
			name = "快速";
			break;
		case VIP:
			name = name();
			break;
		}
		return name;
	}
}

我们使用到了一些常量,我们把他单独封装成一个类:

/*
 * 定义常量类
 * */
public class Constants {
	public static int MAX_SERVICE_TIME = 10000; //每个客户服务最长时间10秒!
	public static int MIN_SERVICE_TIME = 1000; //每个客户服务最短时间1秒!	
}

最后设计主线程:

public class MainClass {
	
	private static Logger logger = Logger.getLogger("cn.itcast.bankqueue");
	

	public static void main(String[] args) {
		//产生4个普通窗口
		for(int i=1;i<5;i++){
			ServiceWindow window =  new ServiceWindow();
			window.setNumber(i);
			window.start();
		}
	
		//产生1个快速窗口
		ServiceWindow expressWindow =  new ServiceWindow();
		expressWindow.setType(CustomerType.EXPRESS);
		expressWindow.start();
		
		//产生1个VIP窗口		
		ServiceWindow vipWindow =  new ServiceWindow();
		vipWindow.setType(CustomerType.VIP);
		vipWindow.start();		
		
		//普通客户拿号
		Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
				new Runnable(){
					public void run(){
						//产生新的普通客户
						Integer serviceNumber = NumberMachine.getInstance().getCommonManager().generateNewNumber();
						/**
						 * 采用logger方式,无法看到直观的运行效果,因为logger.log方法内部并不是直接把内容打印出出来,
						 * 而是交给内部的一个线程去处理,所以,打印出来的结果在时间顺序上看起来很混乱。
						 */
						//logger.info("第" + serviceNumber + "号普通客户正在等待服务!");
						System.out.println("第" + serviceNumber + "号普通客户正在等待服务!");						
					}
				},
				0,//马上就有客户产生
				Constants.COMMON_CUSTOMER_INTERVAL_TIME,
				TimeUnit.SECONDS);
		
		//快速客户拿号
		Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
				new Runnable(){
					public void run(){
						Integer serviceNumber = NumberMachine.getInstance().getExpressManager().generateNewNumber();
						System.out.println("第" + serviceNumber + "号快速客户正在等待服务!");
					}
				},
				0,
				Constants.COMMON_CUSTOMER_INTERVAL_TIME * 2,
				TimeUnit.SECONDS);
		
		//VIP客户拿号
		Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
				new Runnable(){
					public void run(){
						Integer serviceNumber = NumberMachine.getInstance().getVipManager().generateNewNumber();
						System.out.println("第" + serviceNumber + "号VIP客户正在等待服务!");
					}
				},
				0,
				Constants.COMMON_CUSTOMER_INTERVAL_TIME * 6, 
				TimeUnit.SECONDS);
	}

}

这MainClass类中使用到了一些常量,我们把他加到常量类Constants中:

public class Constants {
	public static int MAX_SERVICE_TIME = 10000; //每个客户服务最长时间10秒!
	public static int MIN_SERVICE_TIME = 1000; //每个客户服务最短时间1秒!
	
	/*每个普通窗口服务一个客户的平均时间为5秒,一共有4个这样的窗口,也就是说银行的所有普通窗口合起来
	 * 平均1.25秒内可以服务完一个普通客户,再加上快速窗口和VIP窗口也可以服务普通客户,所以,
	 * 1秒钟产生一个普通客户比较合理,通过让这个变量乘以不同值来控制3种客户间的比例关系*/	
	public static int COMMON_CUSTOMER_INTERVAL_TIME = 1; 	
}

这样我们的银行业务调度系统就设计完成了,我们运行一下可以看到,首先6的窗口都开始工作,准备获取其对应的任务,这个时候还没有客户被创建出来所以他们会等待一秒,在cpu不断的执行中各种类型的客户被创建出来了,就去对应的窗口执行,快速窗口和Vip窗口在没有对应的客户等待的情况下去为普通客户服务,这就是我们这个程序的运行结果。




------ Java培训、Android培训、iOS培训、.Net培训、期待与您交流!-------
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值