黑马程序员技术交流社区

标题: 学习银行业务调度系统后,对代码的一点改进,请大家指正 [打印本页]

作者: 如梦初醒    时间: 2012-4-1 14:36
标题: 学习银行业务调度系统后,对代码的一点改进,请大家指正
在MainClass类中,
new Runnable(){
                    public void run(){
                        Integer serviceNumber = NumberMachine.getInstance().getCommonManager().generateNewNumber();
                        System.out.println("第" + serviceNumber + "号普通客户正在等待服务!");
                    }
                },
                0,

                Constants.COMMON_CUSTOMER_INTERVAL_TIME,

                TimeUnit.SECONDS);

这两段代码    Integer serviceNumber = NumberMachine.getInstance().getCommonManager().generateNewNumber();
                        System.out.println("第" + serviceNumber + "号普通客户正在等待服务!");

不具有原子性所以在运行过程中可能会出现,xx客户已经被服务了,还打印xx客户正在等待服务的情况,如下运行结果:

..........................................................................................

第3号普通窗口开始为第4号普通客户服务
第2号普通窗口开始获取普通任务!
第2号普通窗口开始为第5号普通客户服务
第4号普通窗口开始获取普通任务!
第4号普通窗口没有取到普通任务,正在空闲一秒
第5号普通客户正在等待服务!

.........................................................................................

于是我对源代码进行了一些改进,来避免出现这种服务了还在等待的情况,

改进如下:

//普通客户拿号
        Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
                new Runnable(){
                    public void run(){
//                        Integer serviceNumber = NumberMachine.getInstance().getCommonManager().generateNewNumber();
//                        System.out.println("第" + serviceNumber + "号普通客户正在等待服务!");
                        NumberMachine.getInstance().getCommonManager().generateNewNumber();
                    }
                },
                0,
                Constants.COMMON_CUSTOMER_INTERVAL_TIME,
                TimeUnit.SECONDS);
        
        //快速客户拿号
        Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
                new Runnable(){
                    public void run(){
//                        Integer serviceNumber = NumberMachine.getInstance().getExpressManager().generateNewNumber();
//                        System.out.println("第" + serviceNumber + "号快速客户正在等待服务!");
                        NumberMachine.getInstance().getExpressManager().generateNewNumber();
                    }
                },
                0,
                Constants.COMMON_CUSTOMER_INTERVAL_TIME * 2,
                TimeUnit.SECONDS);
        
        //VIP客户拿号
        Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
                new Runnable(){
                    public void run(){
//                        Integer serviceNumber = NumberMachine.getInstance().getVipManager().generateNewNumber();
//                        System.out.println("第" + serviceNumber + "号VIP客户正在等待服务!");
                        NumberMachine.getInstance().getVipManager().generateNewNumber();
                    }
                },
                0,
                Constants.COMMON_CUSTOMER_INTERVAL_TIME * 6,
                TimeUnit.SECONDS);
    }



public class NumberManager {
    private int lastNumber = 0;
    private List<Integer> queueNumbers = new ArrayList<Integer>();
   
    private String userType=null;
    public NumberManager(String userType){  this.userType= userType;          }
    /*
    public synchronized Integer generateNewNumber(){
        queueNumbers.add(++lastNumber);
        return lastNumber;
    }

   */

  public synchronized  void generateNewNumber(){
        queueNumbers.add(++lastNumber);
        System.out.println("第" + lastNumber + "号"+userType+"正在等待服务!");
        
    }


   public synchronized Integer fetchNumber(){
        if(queueNumbers.size()>0){
            return (Integer)queueNumbers.remove(0);
        }else{
            return null;
        }
    }
}


也就是在类 MainClass 和类NumberManager中将注释部分代码换成粗体部分代码。




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2