黑马程序员——银行业务系统
------- <a href="http://www.itheima.com" target="blank">android培训</a>、<a href="http://www.itheima.com" target="blank">java培训</a>、期待与您交流! ----------
如上图所示因为客户有普通,快速,VIP三种类型所以就得有三种不同类型的产号机,但考虑到实际业务中只有一个取票机,所以把取票机当做可以访问三台不同类型产票机的对象。窗口也分为不同类型的三个窗口,4个普通窗口只办理普通业务(绿线所示),快速窗口可以办理快速业务和普通业务(黄色线条所示),VIP窗口可以办理VIP业务和普通业务(蓝色线条所示)。
下面是做这个系统在写代码之前要重点考虑到的地方:
① 考虑到窗口的类型可以变化,所以可以在窗口队形创建后通过setType()来重新设置窗口类型编号也是一样的道理;
② 因为取号机只有一台,所以使用单例模式;
③ 考虑到产号机的产生编号和移除编号是操作同一个集合,所以使用到同步函数synchronized;
④ 因为窗口的类型数量和种类是确定的所以使用JDK1.5新特性枚举比较好;
⑤start()方法中在判断窗口类型的时候用switch要比使用if else效率高;
⑥创建线程使用JDK1.5新特性Executors.newSingleThreadExecutor()效率高
以下是系统代码:
import java.util.*;
public class NumberManager {
private Integer current=1;
private List<Integer> clients=new ArrayList<Integer>();
public synchronized Integer gererateNumber()//存和取同时操作一个集合所以加上同步
{
clients.add(current);
return current++;
}
public synchronized Integer fetchNumber()//返回值可能是null所以不能用int
{
if(clients.size()>0)
{
return clients.remove(0);
}
else
{
return null;
}
}
}//end
//单例模式之饿汉式
public class NumberMachine {
private NumberManager comman=new NumberManager();
private NumberManager express=new NumberManager();
private NumberManager vip=new NumberManager();
private static NumberMachine instance=new NumberMachine();
public NumberManager getCommanManager()
{
return comman;
}
public NumberManager getExpressManager()
{
return express;
}
public NumberManager getVipManager()
{
return vip;
}
public static NumberMachine getInstance()
{
return instance;
}
}//end
import java.util.Random;
import java.util.concurrent.Executors;
public class ServiceWindow {
private WindowType type=WindowType.COMMANTYPE;
private int windowId=1;
public void setType(WindowType type) {
this.type = type;
}
public void setWindowId(int windowId) {
this.windowId = windowId;
}
public void start()
{
Executors.newSingleThreadExecutor().execute(new Runnable(){//线程池
public void run(){
while(true)
{
switch(type)//比if else 效率高
{
case COMMANTYPE:
commandService();
break;
case EXPRESSTYPE:
expressService();
break;
case VIPTYPE:
vipService();
break;
}
}
}
});
}
private void commandService() {
String windowName="第"+windowId+"号"+type+"窗口";
System.out.println(windowName+"准备获取任务");
Integer number=NumberMachine.getInstance().getCommanManager().fetchNumber();//获取普通顾客
if(number != null)
{
System.out.println(windowName+"正在为"+number+"号"+type+"顾客进行服务");
long beginTime=System.currentTimeMillis();//获取系统当前时间;
int maxRand=Constants.MAX_SERVICE_TIME-Constants.MIN_SERVICE_TIME;
long serverTime=new Random().nextInt(maxRand+Constants.MIN_SERVICE_TIME);//随机范围[1000~10000);
try {
Thread.sleep(serverTime);//线程休眠模拟服务耗时
} catch (Exception e) {
}
long costTime=System.currentTimeMillis()-beginTime;
System.out.println(windowName+"为"+number+"号"+type+"顾客服务完毕用时:"+costTime/1000);
}
else
{
System.out.println(windowName+"没有人来,休息一秒");
try {
Thread.sleep(1000);
} catch (Exception e) {
}
}
}
private void expressService() {
String windowName="第"+windowId+"号"+type+"窗口";
System.out.println(windowName+"准备获取任务");
Integer number=NumberMachine.getInstance().getExpressManager().fetchNumber();
if(number != null)
{
System.out.println(windowName+"正在为"+number+"号"+type+"顾客进行服务");
long beginTime=System.currentTimeMillis();//获取系统当前时间;
try {
Thread.sleep(Constants.MIN_SERVICE_TIME);
} catch (Exception e) {
}
long costTime=System.currentTimeMillis()-beginTime;
System.out.println(windowName+"为"+number+"号"+type+"号顾客服务完毕用时:"+costTime/1000);
}
else
{
System.out.println(windowName+"没有办理快速业务的客户来");
commandService();//再去看有没有客服务的普通客户
}
}
private void vipService() {
String windowName="第"+windowId+"号"+type+"窗口";
System.out.println(windowName+"准备获取任务");
Integer number=NumberMachine.getInstance().getVipManager().fetchNumber();
if(number != null)
{
System.out.println(windowName+"正在为"+number+"号"+type+"顾客进行服务");
long beginTime=System.currentTimeMillis();//获取系统当前时间;
int maxRand=Constants.MAX_SERVICE_TIME-Constants.MIN_SERVICE_TIME;
long serverTime=new Random().nextInt(maxRand+Constants.MIN_SERVICE_TIME);
try {
Thread.sleep(serverTime);
} catch (Exception e) {
}
long costTime=System.currentTimeMillis()-beginTime;
System.out.println(windowName+"为"+number+"号"+type+"顾客服务完毕用时:"+costTime/1000);
}
else
{
System.out.println(windowName+"没有Vip客户来");
commandService();
}
}
}//end
public enum WindowType {
COMMANTYPE,EXPRESSTYPE,VIPTYPE;
public String toString()//覆盖toString()
{
switch(this)
{
case COMMANTYPE:
return "普通";
case EXPRESSTYPE:
return "快速";
case VIPTYPE:
return "VIP";
}
return null;
}
}//end
public class Constants {
public static int MAX_SERVICE_TIME=10000;
public static int MIN_SERVICE_TIME=1000;
}//end
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class Main {
public static void main(String[] args) {
for(int i=1;i<5;i++)
{
ServiceWindow commandWindow=new ServiceWindow();
commandWindow.setType(WindowType.COMMANTYPE);
commandWindow.setWindowId(i);
commandWindow.start();
}
ServiceWindow expressWindow=new ServiceWindow();
expressWindow.setType(WindowType.EXPRESSTYPE);//设置窗口类型
expressWindow.setWindowId(5);//设置窗口编号
expressWindow.start();
ServiceWindow vipWindow=new ServiceWindow();
vipWindow.setType(WindowType.VIPTYPE);
vipWindow.setWindowId(6);
vipWindow.start();
//通过定时器的周期来实现1:6:3
Executors.newScheduledThreadPool(1).scheduleAtFixedRate(new Runnable(){
public void run(){
Integer number=NumberMachine.getInstance().getCommanManager().gererateNumber();
System.out.println(number+"号客户正在等待");
}
},
0,
1,//6秒产生6个
TimeUnit.SECONDS);
Executors.newScheduledThreadPool(1).scheduleAtFixedRate(new Runnable(){
public void run(){
Integer number=NumberMachine.getInstance().getExpressManager().gererateNumber();
System.out.println(number+"号快速客户正在等待");
}
},
0,
2,//6秒产生3个
TimeUnit.SECONDS);
Executors.newScheduledThreadPool(1).scheduleAtFixedRate(new Runnable(){
public void run(){
Integer number=NumberMachine.getInstance().getVipManager().gererateNumber();
System.out.println(number+"号VIP客户正在等待");
}
},
0,
6,//6秒产生1个 这样就实现了1:6:3
TimeUnit.SECONDS);
}
}