A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 杨栋 中级黑马   /  2013-9-2 15:14  /  1585 人查看  /  2 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 杨栋 于 2013-9-2 15:16 编辑


如上图所示因为客户有普通,快速,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);

    }

}

2 个回复

倒序浏览
值得学习ing!
回复 使用道具 举报

哇 这么多技术分,

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马