package cn.itcast.bank;
import java.util.ArrayList;
public class NumberManager {
private int lastNumber=1;
private ArrayList<Integer> queueNumber=new ArrayList<Integer>();
public synchronized int generateNewManager(){
queueNumber.add(lastNumber);
return lastNumber++;
}
public synchronized Integer fetchServiceNumber(){
Integer number=null;
if(queueNumber.size()>0){
number=queueNumber.remove(0);
}
return number;
}
}package cn.itcast.bank;
public class NumberMachine {
private NumberManager commonManager=new NumberManager();
private NumberManager expressManager=new NumberManager();
private NumberManager vipManager=new NumberManager();
public NumberManager getCommonManager(){
return commonManager;
}
public NumberManager getExpressManager(){
return expressManager;
}
public NumberManager getVipManager(){
return vipManager;
}
//用单例设计模式实现取号机器NumberMachine,这样commonManager、expressManager、vipManager也内存中也就分别只有一个对象,各自按顺序生成号码。
private NumberMachine(){}
public static NumberMachine getInstance(){
return instance;
}
private static NumberMachine instance=new NumberMachine();
}package cn.itcast.bank;
/*
* 业务类型枚举值
*/
public enum CustomerType {
COMMON,EXPRESS,VIP;
public String toString(){
switch(this){
case COMMON:
return "普通";
case EXPRESS:
return "快速";
case VIP:
return name();
}
return null;
}
}package cn.itcast.bank;
public class Constants {
//最大和最小服务时间
public static int MAX_SERVICE_TIME=10000;
public static int MIN_SERVICE_TIME=1000;
//普通客户到来的时间间隔
public static int COMMON_CUSTOMER_INTERVAL_TIME=1;
}package cn.itcast.bank;
/*
* 业务窗口类
*/
import java.util.Random;
import java.util.concurrent.Executors;
public class ServiceWindow {
private CustomerType type=CustomerType.COMMON;
public void setType(CustomerType type) {
this.type = type;
}
private int windowId=1;
public void setWindowId(int windowId) {
this.windowId = windowId;
}
public void start(){
Executors.newSingleThreadExecutor().execute(new Runnable(){
@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+"窗口";
Integer number=NumberMachine.getInstance().getCommonManager().fetchServiceNumber();
System.out.println(windowName+"正在获取普通任务!");
if(number!=null){
System.out.println(windowName+"为第"+number+"号普通客户服务!");
//普通窗口的服务时间是随机的,在最大服务时间与最小服务时间之间
int maxRand=Constants.MAX_SERVICE_TIME-Constants.MIN_SERVICE_TIME;
long serviceTime=new Random().nextInt(maxRand)+1+Constants.MIN_SERVICE_TIME;
try {
Thread.sleep(serviceTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(windowName+"为第"+number+"个普通客户完成服务,耗时"+serviceTime/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+"窗口";
Integer number=NumberMachine.getInstance().getExpressManager().fetchServiceNumber();
System.out.println(windowName+"正在获取快速任务!");
if(number!=null){
System.out.println(windowName+"为第"+number+"号快速客户服务!");
//快速窗口的服务时间是最短的
long serviceTime=Constants.MIN_SERVICE_TIME;
try {
Thread.sleep(serviceTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(windowName+"为第"+number+"个"+type+"客户完成服务,耗时"+serviceTime/1000+"秒");
}
else{
System.out.println(windowName+"没有取到快速任务!");
//快速窗口没有任务时可以为普通客户服务
commonService();
}
}
private void vipService() {
String windowName="第"+windowId+"号"+type+"窗口";
Integer number=NumberMachine.getInstance().getVipManager().fetchServiceNumber();
System.out.println(windowName+"正在获取VIP任务!");
if(number!=null){
System.out.println(windowName+"为第"+number+"号VIP客户服务!");
//VIP窗口的服务时间也是随机的,在最大服务时间与最小服务时间之间
int maxRand=Constants.MAX_SERVICE_TIME-Constants.MIN_SERVICE_TIME;
long serviceTime=new Random().nextInt(maxRand)+1+Constants.MIN_SERVICE_TIME;
try {
Thread.sleep(serviceTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(windowName+"为第"+number+"个"+type+"客户完成服务,耗时"+serviceTime/1000+"秒");
}
else{
System.out.println(windowName+"没有取到VIP任务!");
//VIP窗口没有任务时可以为普通客户服务
commonService();
}
}
}package cn.itcast.bank;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class MainClass {
public static void main(String[] args) {
//产生4个普通窗口
for(int i=1;i<5;i++){
ServiceWindow commonWindow=new ServiceWindow();
commonWindow.setWindowId(i);
commonWindow.start();
}
//产生一个快速窗口
ServiceWindow expressWindow=new ServiceWindow();
expressWindow.setType(CustomerType.EXPRESS);
expressWindow.start();
//产生一个VIP窗口
ServiceWindow vipWindow=new ServiceWindow();
vipWindow.setType(CustomerType.VIP);
vipWindow.start();
//普通客户拿号
Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
new Runnable(){
@Override
public void run() {
Integer number=NumberMachine.getInstance().getCommonManager().generateNewManager();
System.out.println("第"+number+"号普通客户正在等待服务!");
}
},
0,
Constants.COMMON_CUSTOMER_INTERVAL_TIME,
TimeUnit.SECONDS);
//快速客户拿号
Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
new Runnable(){
@Override
public void run() {
Integer number=NumberMachine.getInstance().getExpressManager().generateNewManager();
System.out.println("第"+number+"号快速客户正在等待服务!");
}
},
0,
Constants.COMMON_CUSTOMER_INTERVAL_TIME*3,
TimeUnit.SECONDS);
//VIP客户拿号
Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
new Runnable(){
@Override
public void run() {
//下面这2句不应该分开执行,应该作为一个整体执行,但因generateNewManager()方法中加锁,此外再加锁易造成死锁
Integer number=NumberMachine.getInstance().getVipManager().generateNewManager();
System.out.println("第"+number+"号VIP客户正在等待服务!");
}
},
0,
Constants.COMMON_CUSTOMER_INTERVAL_TIME*6,
TimeUnit.SECONDS);
}
}黑马程序员-java 7K面试题之银行业务调度系统,布布扣,bubuko.com
原文地址:http://blog.csdn.net/chen_yuyunfox/article/details/28091657