[黑马程序员]银行系统-跟着张老师敲代码

这个写在最前面,是让为了日后学习内容当个参考:

1。23种设计模式

2。类图 ->流程图->状态图

3。rose

4。突然想起来UML。。。


其实,这个题拿到之后,按照习惯,没有先直接继续看,而是把自己的思路整理了下,看自己按照现在的水平能不能完成.

思路大概如下:

对象:

银行业务窗口(包含里面的业务处理),客户,业务类型。


具体点儿:

1.业务类型有三类:普通,快速,vip,用枚举

2.客户的类型有三类:普通,快速,vip,通过set方法从业务类型来。 

3.窗口:数量6个。1-4 处理普通业务,5处理vip业务,6处理快速业务。

              窗口处理业务的类型,通过set方法确定,处理业务的时间,通过本身的属性确定。(这个处理的不如张老师,没想到定义常量。)

4.还需要3个队列,这里用List<Customer>[] queue=new ArrayList<Customer>()来确定。搞出3个队列,分别存储不同类型的顾客。

5.随机用线程产生不同类型客户,然后加到相应队列。(没有张老师的叫号器,呵呵,看来观察生活很重要啊。)

6.vip/快速两个窗口处理完之后,要帮助处理普通类型。

7.普通队列,因为最少被4个,最多被6个窗口操作,所以要加锁。


场景:

简单来讲,就是一个舞台,9条线程。

3个线程分别按照比例产生三种类型客户,

6个线程,代表6个业务窗口,开始处理业务。


普通窗口,只是轮询普通业务用户队列,

vip,先轮询vip队列,后普通队列

快速,先轮询快速,后普通队列。


总体下来,感觉这个题,比前面的交通灯的题要简单。首先舞台上的演员少,其次是业务逻辑简单。


下面是看视频中跟着老师敲的代码。

发现,张老师的思路确实是值得学习。

1.分析的时候,一定要结合生活的常识。

2.拆类的时候,一定要本着谁有数据,谁就对外提供操作方法的宗旨。

3.一定要时不时的让自己开心一下,呵呵,这点很重要,这就是快乐的源泉阿。

4.要了解和实践新技术


NumberManager.java

package com.linuxgg.interview.bank;

import java.util.*;

public class NumberManager {

	private int lastNumber = 1;
	private List<Integer> queueNumber = new ArrayList<Integer>();

	//多线程要操作同一份数据,要加互斥
	public synchronized Integer generateNewNumber() {
		queueNumber.add(lastNumber);
		return lastNumber++;
	}

	public synchronized Integer fetchServiceNumber() {
		if(queueNumber.size()>0){
			return queueNumber.remove(0);
		}else{
			return null;
		}
		
	}

}


NumberMachine.java

package com.linuxgg.interview.bank;

public enum CustomerType {
	COMMON, EXPRESS, VIP;

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

		}
		return null;
	}
}

ServiceWindow.java

package com.linuxgg.interview.bank;

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

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

	public void start() {
		Executors.newSingleThreadExecutor().execute(new Thread() {
			@Override
			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+"窗口";
		System.out.println(windowName + "正在获取任务");
		Integer number = NumberMachine.getInsatance().getCommonManager()
				.fetchServiceNumber();
		if (number != null) {
			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 {
				System.out.println(windowName + "正在为第["+number+"]任务");
				Thread.sleep(serveTime);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				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) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	private void exPressService() {
		String windowName = ">>第" + windowID + "号" + type + "窗口";
		System.out.println(windowName + "正在获取任务");
		Integer number = NumberMachine.getInsatance().getExpressManager()
				.fetchServiceNumber();
		if (number != null) {
			long beginTime = System.currentTimeMillis();

			try {
				Thread.sleep(Constants.MIN_SERVICE_TIME);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			long costTime = System.currentTimeMillis() - beginTime;
			System.out.println(windowName + "为第[" + number + "]个" + type
					+ "[快速]客户完成服务,耗费:" + (costTime / 1000) + "秒");

		} else {
			System.out.println(windowName + "没有取到[快速]任务号。开始服务普通业务。");
			commonService();

		}
	}

	private void vipService() {
		String windowName = ">>>第" + windowID + "号" + type + "窗口";
		System.out.println(windowName + "正在获取任务");
		Integer number = NumberMachine.getInsatance().getExpressManager()
				.fetchServiceNumber();
		if (number != null) {
			long beginTime = System.currentTimeMillis();

			try {
				Thread.sleep(Constants.MIN_SERVICE_TIME);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			long costTime = System.currentTimeMillis() - beginTime;
			System.out.println(windowName + "为第[" + number + "]个" + type
					+ "[vip]客户完成服务,耗费:" + (costTime / 1000) + "秒");

		} else {
			System.out.println(windowName + "没有取到[vip]任务号。开始为普通客户服务。");
			commonService();
		}
	}
}

Constants.java

package com.linuxgg.interview.bank;

public class Constants {

	public static int MAX_SERVICE_TIME = 10000;
	public static int MIN_SERVICE_TIME = 1000;
	//其实这个取值,我觉得如下更好:
	//1。去到3种服务的最大公倍数:6
	//2。用设定的最大公倍数去出比率,就是应该设定的时间。COMMON_CUSTOMER_INTERVAL_TIME/n
	//3。这么做的好处,就是不用再去考虑计算后面的两个比率的时间设定问题。
	public static int COMMON_CUSTOMER_INTERVAL_TIME=1;

}


CustomerType.java

package com.linuxgg.interview.bank;

public enum CustomerType {
	COMMON, EXPRESS, VIP;

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

		}
		return null;
	}
}

MainClass.java

package com.linuxgg.interview.bank;

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

public class MainClass {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// 启动一般服务窗口
		for (int i = 1; i < 5; i++) {
			ServiceWindow commonWindow = new ServiceWindow();
			commonWindow.setWindowID(i);
			commonWindow.start();
		}
		// 启动vip服务窗口
		ServiceWindow vipWindow = new ServiceWindow();
		vipWindow.setType(CustomerType.VIP);
		vipWindow.start();
		// 启动快速服务窗口
		ServiceWindow expressWindow = new ServiceWindow();
		expressWindow.setType(CustomerType.EXPRESS);
		expressWindow.start();

		// 产生普通号
		Executors.newScheduledThreadPool(1).scheduleAtFixedRate(new Runnable() {
			@Override
			public void run() {
				Integer number = NumberMachine.getInsatance()
						.getCommonManager().generateNewNumber();
				System.out.println(number + "号普通客户等待服务");
			}

		}, 0, Constants.COMMON_CUSTOMER_INTERVAL_TIME, TimeUnit.SECONDS);

		// 产生vip号
		Executors.newScheduledThreadPool(1).scheduleAtFixedRate(new Runnable() {
			@Override
			public void run() {
				Integer number = NumberMachine.getInsatance().getVipManager()
						.generateNewNumber();
				System.out.println(number + "号VIP客户等待服务");

			}

		}, 0, Constants.COMMON_CUSTOMER_INTERVAL_TIME * 6, TimeUnit.SECONDS);
		// 产生快速号
		Executors.newScheduledThreadPool(1).scheduleAtFixedRate(new Runnable() {
			@Override
			public void run() {
				Integer number = NumberMachine.getInsatance()
						.getExpressManager().generateNewNumber();
				System.out.println(number + "号快速客户等待服务");

			}

		}, 0, Constants.COMMON_CUSTOMER_INTERVAL_TIME * 2, TimeUnit.SECONDS);

	}

}


题干贴到这里:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值