------- android培训、java培训、期待与您交流! ----------
看了张老师关于银行业务调度系统的视频和源代码,非常佩服张老师的技术功底和面向对象的思想。同时也产生了一些自己的想法和对张老师代码的一些不足之处的改建意见。
一、系统的取号机只有三种方式的取号(普通客户,快速客户,vip客户),所以采用枚举的方式是比较合适的,因为枚举能产生固定个数的对象,用起来也比较方便。
二、创建普通服务窗口类,下面有两个子类(快速服务窗口和vip服务窗口)。这一点张老师在视频中也讲了,不过没有在课堂上实现,我把它实现了,这样就提高了代码的复用性。
三、根据系统需求的描述,是6个窗口按次序排列,1 -4号窗口为普通窗口,5号窗口为快速窗口,6号窗口为VIP窗口。而不是1号快速窗口和1号VIP窗口,这一点我也做了改进,更符合项目要求。
四、服务窗口不用每隔1秒检查,服务完后就检查是否有客户等待服务,而且最好不打印“没取得任务,空闲一秒”,因为作为模拟场景的输出,这样的阅读性不是很好。
五、客户取得号码的时候显示前面有几人在排队字样,如“9号VIP客户,欢迎光临,您前面有1位客户”,这样更符合真实场景。
六、按照项目需求的要求,异步随机生成各种类型的客户,生成各类型用户的概率比例为: VIP客户 :普通客户 :快速客户 = 1 :6 :3,所以满足比例的同时,具体时间也应该是随机的,而不是固定的。
七、我是站在巨人的肩膀上完成这个项目的,张老师教给了我们很好的思路,我只是做了小小的改进。
根据以上几条意见,我试着编了一下代码,如下:
package com.itheima;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public enum QueueMachine {
COMMON, EXPRESS, VIP;
private List<Integer> commonList = new ArrayList<Integer>();
private List<Integer> expressList = new ArrayList<Integer>();
private List<Integer> vipList = new ArrayList<Integer>();
private static Integer customerNum = 1;// commonNum=1,expressNum=1,vipNum=1;
public String toString() {
String type = null;
if (this == COMMON)
type = "普通客户";
if (this == EXPRESS)
type = "快速客户";
if (this == VIP)
type = "VIP客户";
return type;
}
public synchronized void start() {
long period = 0;
switch (this) {
case COMMON:
period = new Random().nextInt(3) + 1;
break;
case EXPRESS:
period = new Random().nextInt(6) + 1;
break;
case VIP:
period = new Random().nextInt(18) + 1;
break;
}
Executors.newScheduledThreadPool(1).scheduleAtFixedRate(new Runnable() {
public void run() {
switch (QueueMachine.this) {// 重点
case COMMON:
System.out.println(customerNum + "号普通业务客户,欢迎光临,您前面有"
+ commonList.size() + "位客户");
commonList.add(customerNum++);
break;
case EXPRESS:
System.out.println(customerNum + "号快速业务客户,欢迎光临,您前面有"
+ expressList.size() + "位客户");
expressList.add(customerNum++);
break;
case VIP:
System.out.println(customerNum + "号VIP客户,欢迎光临,您前面有"
+ vipList.size() + "位客户");
vipList.add(customerNum++);
break;
}
}
}, 0, period, TimeUnit.SECONDS);
}
public synchronized Integer fetchNum() {
Integer fn = null;
switch (this) {
case COMMON:
if (commonList.size() > 0)
fn = commonList.remove(0);
break;
case EXPRESS:
if (expressList.size() > 0)
fn = expressList.remove(0);
break;
case VIP:
if (vipList.size() > 0)
fn = vipList.remove(0);
break;
}
return fn;
}
}
package com.itheima;
import java.util.Random;
import java.util.concurrent.Executors;
public class ServiceWindow {
public int windowNum=1;
public QueueMachine type=QueueMachine.COMMON;
public static final int MIN_TIME=1000,MAX_TIME=3000;
public ServiceWindow(int windowNum,QueueMachine type){
this.type=type;
this.windowNum=windowNum;
}
public void start(){
Executors.newSingleThreadExecutor().execute(new Runnable(){
public void run(){
System.out.println("服务窗口"+windowNum+"("+type.toString()+")开启!");
while(true){
Integer customerNum = fetchNum();
if (customerNum!=null){
System.out.println("窗口"+windowNum+"为"+type.toString()+customerNum+"服务!");
long startTime=System.currentTimeMillis();
int serviceTime=MIN_TIME+(new Random().nextInt(MAX_TIME-MIN_TIME)+1);
try {
sleepTime(serviceTime);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
long endTime=System.currentTimeMillis();
System.out.println("窗口"+windowNum+"为"+type.toString()+
customerNum+"服务完毕!耗时"+(endTime-startTime)/1000+"秒");
}
else{
extend();
}
}
}
});
}
protected Integer fetchNum() {
Integer customerNum=QueueMachine.COMMON.fetchNum();
return customerNum;
}
protected void sleepTime(int serviceTime)
throws InterruptedException {
Thread.sleep(serviceTime);
}
protected void extend(){
}
}
class ExpressServiceWindow extends ServiceWindow{
public int windowNum=5;
public QueueMachine type=QueueMachine.EXPRESS;
public ExpressServiceWindow(int windowNum,QueueMachine type){
super(windowNum, type);
this.type=type;
this.windowNum=windowNum;
}
protected Integer fetchNum() {
Integer customerNum=QueueMachine.EXPRESS.fetchNum();
return customerNum;
}
protected void sleepTime(int serviceTime)
throws InterruptedException {
Thread.sleep(MIN_TIME);
}
protected void extend(){
Integer commonCustomerNum =QueueMachine.COMMON.fetchNum();
if (commonCustomerNum!=null){
System.out.println("窗口"+windowNum+"为"+"普通客户"+commonCustomerNum+"服务!");
long startTime=System.currentTimeMillis();
int serviceTime=MIN_TIME+(new Random().nextInt(MAX_TIME-MIN_TIME)+1);
try {
Thread.sleep(serviceTime);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
long endTime=System.currentTimeMillis();
System.out.println("窗口"+windowNum+"为"+"普通客户"+
commonCustomerNum+"服务完毕!耗时"+(endTime-startTime)/1000+"秒");
}
}
}
class VipServiceWindow extends ServiceWindow{
public int windowNum=6;
public QueueMachine type=QueueMachine.VIP;
public VipServiceWindow(int windowNum,QueueMachine type){
super(windowNum, type);
this.type=type;
this.windowNum=windowNum;
}
protected Integer fetchNum() {
Integer customerNum=QueueMachine.EXPRESS.fetchNum();
return customerNum;
}
protected void sleepTime(int serviceTime)
throws InterruptedException {
Thread.sleep(serviceTime);
}
protected void extend(){
Integer commonCustomerNum =QueueMachine.COMMON.fetchNum();
if (commonCustomerNum!=null){
System.out.println("窗口"+windowNum+"为"+"普通客户"+commonCustomerNum+"服务!");
long startTime=System.currentTimeMillis();
int serviceTime=MIN_TIME+(new Random().nextInt(MAX_TIME-MIN_TIME)+1);
try {
sleepTime(serviceTime);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
long endTime=System.currentTimeMillis();
System.out.println("窗口"+windowNum+"为"+"普通客户"+
commonCustomerNum+"服务完毕!耗时"+(endTime-startTime)/1000+"秒");
}
}
}
package com.itheima;
public class MainClass {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
for(int i=1;i<5;i++){
ServiceWindow sw=null;
sw=new ServiceWindow(i,QueueMachine.COMMON);
sw.start();
}
new ExpressServiceWindow(5,QueueMachine.EXPRESS).start();
new VipServiceWindow(6,QueueMachine.VIP).start();
QueueMachine.COMMON.start();
QueueMachine.EXPRESS.start();
QueueMachine.VIP.start();
}
}
运行结果如下: