这个写在最前面,是让为了日后学习内容当个参考:
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);
}
}
题干贴到这里: