黑马程序员——银行业务排队系统
------- android培训、java培训、期待与您交流! ----------
需求:具有六个窗口,四个普通窗口,一个快速窗口,一个vip窗口;
普通窗口:只为普通用户服务。
快速窗口:优先为快速窗口服务,再为普通窗口服务。
VIP窗口,优先为VIP窗口服务,再为普通窗口服务。
服务时间:最大值与最小值,最小值都是快速客户。
客户出现比例。普通:快速:VIP = 6:3:1
package com.bank;
import java.util.ArrayList;
import java.util.List;
//描述一个管理号码的类
public class NumManage {
//记录号码值
private int lastNum=1;
//维护一个集合,用来存储取走的号码即排队的号码
private List<Integer> queueNum = new ArrayList<Integer>();
//机器产生新号码
public synchronized Integer newManage(){//多线程执行执行同一个资源时加上同步
//每产生一个号码存储到集合中
queueNum.add(lastNum);
return lastNum++;
}
//服务窗口叫号方法
public synchronized Integer fetchNum(){//使用Integer,因为集合存储的是对象,避免空指针异常
Integer num =null;
//当集合中有号码时,取走
if(queueNum.size()>0){
num = queueNum.remove(0);
}
return num;
}
}
package com.bank;
//控制号码的机器
public class NumMachine {
//机器产生三种类型的号码对象
private NumManage commonNum = new NumManage();
private NumManage fastNum = new NumManage();
private NumManage vipNum = new NumManage();
//获取号码对象
public NumManage getCommonNum() {
return commonNum;
}
public NumManage getFastNum() {
return fastNum;
}
public NumManage getVipNum() {
return vipNum;
}
//由于号码机器只有一台,所以私有化构造函数
private NumMachine(){}
//创建本来对象
private static NumMachine instance = new NumMachine();
//提供公共的方法
public static NumMachine getInstance(){
return instance;
}
}
三:定义服务时间常量类
package com.bank;
//定义一个常量类
public class Conts {
//服务最大时间
public static int MAX_TIME=10000;
//服务最小时间
public static int MIN_TIME=1000;
}
四:服务窗口类
package com.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.newSingleThreadScheduledExecutor().execute(new Runnable(){
//线程执行的任务
public void run(){
while(true){
switch(type){
case COMMON:
commonServer();
break;
case FAST:
fastServer();
break;
case VIP:
vipServer();
break;
}
}
}
});
}
//普通客服执行任务
private void commonServer() {
String windowName = "第"+ windowID + "号"+ type + "窗口";
//返回窗口叫号的号码
Integer num = NumMachine.getInstance().getCommonNum().fetchNum();
System.out.println(windowName+"正在获取任务...");
if(num !=null){
System.out.println(windowName+"为第"+num+"个"+"普通"+"客户服务");
//服务开始的时间
long beginTime = System.currentTimeMillis();
//服务时间随机差
int maxRand = Conts.MAX_TIME-Conts.MIN_TIME;
long serveTime = new Random().nextInt(maxRand)+1+Conts.MIN_TIME;
try {
//小睡一会
Thread.sleep(serveTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
//服务花费的时间
long costTime = System.currentTimeMillis()-beginTime;
System.out.println(windowName+"为第"+num+"个"+"普通"+"客户完成服务,耗时"+costTime/1000+"秒");
}else{
System.out.println(windowName+"没有取到任务,先抽根烟...");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
//快速客服执行任务
private void fastServer() {
String windowName = "第"+ windowID + "号"+ type + "窗口";
//返回窗口叫号的号码
Integer num = NumMachine.getInstance().getFastNum().fetchNum();
System.out.println(windowName+"正在获取任务...");
if(num !=null){
System.out.println(windowName+"为第"+num+"个"+type+"客户服务");
//服务开始的时间
long beginTime = System.currentTimeMillis();
try {
//快速客服服务的最小值
Thread.sleep(Conts.MIN_TIME);
} catch (InterruptedException e) {
e.printStackTrace();
}
//服务花费的时间
long costTime = System.currentTimeMillis()-beginTime;
System.out.println(windowName+"为第"+num+"个"+type+"客户完成服务,耗时"+costTime/1000+"秒");
}else{
System.out.println(windowName+"没有取到任务,去为普通客服服务...");
//调用普通服务方法
commonServer();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
//vip客服执行任务
private void vipServer() {
String windowName = "第"+ windowID + "号"+ type + "窗口";
//返回窗口叫号的号码
Integer num = NumMachine.getInstance().getVipNum().fetchNum();
System.out.println(windowName+"正在获取任务...");
if(num !=null){
System.out.println(windowName+"为第"+num+"个"+type+"客户服务");
//服务开始的时间
long beginTime = System.currentTimeMillis();
int maxRand = Conts.MAX_TIME-Conts.MIN_TIME;
long serveTime = new Random().nextInt(maxRand)+1+Conts.MIN_TIME;
try {
Thread.sleep(serveTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
//服务花费的时间
long costTime = System.currentTimeMillis()-beginTime;
System.out.println(windowName+"为第"+num+"个"+type+"客户完成服务,耗时"+costTime/1000+"秒");
}else{
System.out.println(windowName+"没有取到任务,去为普通客服服务...");
//调用普通服务方法
commonServer();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
五:对三种类型顾客描述
package com.bank;
//顾客类型
public enum CustomerType {
COMMON,FAST,VIP;
public String toString() {
switch(this){
case COMMON:
return "普通";
case FAST:
return "快速";
case VIP:
return name();
}
return null;
}
}
六: 主程序:开启三种类型窗口,模拟随机产生三种类型号码。
package com.bank;
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 common = new ServiceWindow();
common.setWindowID(i);//设置窗口名字
common.start();
}
//快速窗口启动
ServiceWindow fast = new ServiceWindow();
fast.setType(CustomerType.FAST);
fast.start();
//vip窗口启动
ServiceWindow vip = new ServiceWindow();
vip.setType(CustomerType.VIP);
vip.start();
//从线程池调用线程
Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
new Runnable(){
//线程执行的任务
public void run(){
Integer num = NumMachine.getInstance().getCommonNum().newManage();
System.out.println(num+ "号普通客服等待服务!");
}
},
0,
6,
TimeUnit.SECONDS);
//从线程池调用线程
Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
new Runnable(){
//线程执行的任务
public void run(){
Integer num = NumMachine.getInstance().getFastNum().newManage();
System.out.println(num+ "号快速客服等待服务!");
}
},
0,
6,
TimeUnit.SECONDS);
//从线程池调用线程
Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
new Runnable(){
//线程执行的任务
public void run(){
Integer num = NumMachine.getInstance().getVipNum().newManage();
System.out.println(num+ "号Vip客服等待服务!");
}
},
0,
6,
TimeUnit.SECONDS);
}
}