代码改变世界

银行业务调度系统

2014-06-04 16:35  黑马程序员*  阅读(345)  评论(0编辑  收藏  举报

设计思路:

(1)有三种对应类型的客户:VIP客户,普通客户,快速客户,异步随机生成各种类型的客户,各类型客户在其对应窗口按顺序依次办理业务。

(2)有三个类。NumberManager类,NumberMachine类,Serverwindow类(抽象类,有三个子类

(一)NumberMachinery类

   1.NumberManage对象总共有三个,由NumberMachinery控制,所以定义成三个成员变量。

   2.NumberMachinery是唯一的,所以使用单例设计。

代码如下: 

public class Numbermachinery {
    /**该类使用单例设计模式
     *使用饿汉式      */
     private Numbermachinery(){
         
     }
     private static final Numbermachinery numberMacInstance = new Numbermachinery();
     private static Numbermanager com = new Numbermanager();
     private static Numbermanager exp = new Numbermanager();
     private static Numbermanager vip = new Numbermanager();     
     public static Numbermachinery getInstance(){
         return numberMacInstance;
     }
     public Numbermanager commonNumber(){
         return  com;
     }
     public Numbermanager expressNumber(){
         return  exp;
     }
     public Numbermanager vipNumber(){
         return vip;
     }
}

 (二)NumberManager类 

有两个方法:generateNumber()产生号码,fetchNunber()对外提供获取号码的方法。 

  1.因为要频繁的增删,所有使用LinkedList集合。 

  2.两个方法都涉及不同的线程,所以要实现同步。 

  3.对于获取null号码,为避免空指针,让它返回-1 

代码如下:  

import java.util.LinkedList;
public class Numbermanager {
    /**两个方法。
     * 一个产生号码,一个提供外界对号码的访问     * */
    int num=0;     
  //存储号码的容器
LinkedList<Integer> link = new LinkedList<Integer>();
//产生号码的方法 public synchronized int numberGenerate() { link.offerLast(++num); return num; } //提供获取号码的方法 public synchronized Integer fetchNumber(){ Integer num = link.pollFirst(); if(num==null){ return -1; } else{ return num; } } }

(三)Numbertype 枚举类
    1.将三种类型的客户用一个枚举类来表示,非常方便,其中定义的三个成员分别表示三种类型的客户。
    2.覆盖toString方法,返回类型的中文名称。

代码如下:

package bankdemo;
    public enum Numbertype {
    COMMON,EXPRESS,VIP;
    public String toString(){
        if(this==Numbertype.COMMON){
            return "普通";
        }
        if(this==Numbertype.EXPRESS){
            return "快速";
        }
        else
            return "VIP";         
    }
}

 

(四)ServerWindow类。

 因为三个类有共同的功能但是功能主体不同,所以抽取父类,让这三个类继承。考虑到现实中,普通窗口可以随时变成VIP窗口和快速窗口。也可以定义成一个类,三个方法。 

  1.三个类继承抽象类。

  2.内被定义一个线程,让三个窗口实现轮流叫号。

  3.抽象方法用于显示信息,和耗时的计算。

代码如下:

import java.util.Random;
import java.util.concurrent.Executors;
public abstract class Serverwindow {
    public  Numbertype type= Numbertype.COMMON;
    public  int windowId=1; 
    public String windowName;
    public void setType(Numbertype type){ 
        this.type=type;
    }
    public void setWindowId(int windowId){
        this.windowId=windowId;     
    }     
    public void windowServer() {
        Executors.newSingleThreadExecutor().execute(new Runnable(){             
            public  void run(){//注意while循环的放置位置,要在一个线程run方法中。                 
                 while(true){                 
                     try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e2) {                         
                        e2.printStackTrace();
                    }                     
                    Integer num = getNum();
                    windowName = windowId+ "号" + type + "窗口";
                    try {
                        Thread.sleep(1500);
                    } catch (InterruptedException e1) {                     
                        e1.printStackTrace();
                    }
                    if (num == -1) {
                        print1();                         
                        helpWindow();
                    } else {                 
                        print2(num);                         
                        long start = System.currentTimeMillis();                     
                        long serverTime = getServerTime();
                        try {                            
                            Thread.sleep(serverTime);                         
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        long end = System.currentTimeMillis();
                        print3(num, end - start);
                    }
                }
            }                              
        });        
    }     
    public abstract void print1();//显示没有获取到任务的信息,
    public abstract void print2(int num);//显示开始服务的信息
    public abstract void print3(int num,long time);//显示服务的时间的信息
    public abstract void helpWindow();//快速窗口和VIP窗口对普通窗口服务
    public abstract long getServerTime();//服务时间
    public abstract int getNum();//获取号码
}

class CommonServerWindow extends Serverwindow{        
    public void print1(){
        System.out.println( windowName+"没有获取到普通客户服务>>>>>");
        System.out.println(windowName + "休息1秒");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {                             
            e.printStackTrace();
        }
    }    
    public void print2(int num){
        System.out.println( windowName+"获取到"+num+"号普通服务,开始服务");
    }    
    public void print3(int num,long time){
        System.out.println( windowName+"为"+num+"号普通客户服务完毕,耗时"+time+"秒");
    }    
    public void helpWindow(){        
    }     
    public long getServerTime() {     
        long serverTime =new Random().nextInt((ConstantDemo.MAX-ConstantDemo.MIN)/1000)+1;
        return serverTime*1000+ConstantDemo.MIN;
    }      
    public int getNum() {     
        return   Numbermachinery.getInstance().commonNumber()
                .fetchNumber();
    }
} 

class ExpressServerWindow extends Serverwindow{     
    public void print1() {    
        System.out.println(windowName+"没有获取到快速客户服务》》》");    
        System.out.println(windowName + "休息1秒");
    }     
    public void print2(int num) {         
        System.out.println(windowName+"获取到"+num+"号快速服务,开始服务");
    } 
    public void print3(int num, long time) {         
        System.out.println(windowName+"为"+num+"号.快速客户服务完毕,耗时"+time+"秒");
    }
    public void helpWindow() {    //快速窗口为普通客户服务 
        CommonServerWindow cs=new CommonServerWindow();
        cs.setType(Numbertype.EXPRESS);
        cs.setWindowId(1);
        cs.windowServer();              
    }     
    public long getServerTime() {     
        return ConstantDemo.MIN;
    } 
    public int getNum() {         
        return  Numbermachinery.getInstance().expressNumber()
                .fetchNumber();
    }    
}
class VIPServerWindow extends Serverwindow{     
    public void print1() {
        System.out.println(windowName+"没有获取到VIP客户服务");    
        System.out.println(windowName + "休息1秒");
    }     
    public void print2(int num) {
        System.out.println(windowName+"获取到"+num+"号VIP服务,开始服务");        
    }
    public void print3(int num, long time) {
        System.out.println(windowName+"为"+num+"号..VIP客户服务完毕,耗时"+time+"秒");    
    }     
    public void helpWindow() {//VIP窗口为普通客户服务 
        CommonServerWindow cs=new CommonServerWindow();
        cs.setType(Numbertype.VIP);
        cs.setWindowId(1);
        cs.windowServer();      
    }     
    public long getServerTime() {         
        return ConstantDemo.MAX;
    } 
    public int getNum() {
         
        return  Numbermachinery.getInstance().vipNumber()
                .fetchNumber();
    }
    
}

(五)常量的类  

public class ConstantDemo { 
         public static final int MAX=3000;
         public static final int MIN=1000;          
}

(六)mian方法。

  1.使用for循环,产生四个普通窗口。而快速窗口和VIP窗口,设定为只有一个窗口。

  2.使用Executors线程工具类,产生三个单独的线程,进行产生号码。

import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit; 
public class MainDemo {     
    public static void main(String[] args) {
         //设置4个普通窗口        
            for(int x=1;x<5;x++){                
                CommonServerWindow commonwindow  = new CommonServerWindow();//new 4次
                commonwindow.setWindowId(x);
                commonwindow.setType(Numbertype.COMMON);                
                commonwindow.windowServer();             
            }            
            Serverwindow expresswindow = new ExpressServerWindow();
            expresswindow.setType(Numbertype.EXPRESS);
            expresswindow.windowServer();
            
            VIPServerWindow vipwindow=  new VIPServerWindow();
            vipwindow.setType(Numbertype.VIP);
            vipwindow.windowServer();
            
            Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
                    new Runnable(){         
                        public void run() {
                         Integer num = Numbermachinery.getInstance().commonNumber().numberGenerate();
                        if(num!=null){                    
                            System.out.println("普通客户"+num+"号等待服务");
                        }                
                        }            
                    } ,
                    0, 
                    1,
                    TimeUnit.SECONDS
                    );
            Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
                    new Runnable(){         
                        public void run() {
                            Integer num =Numbermachinery.getInstance().expressNumber().numberGenerate();;
                        if(num!=null){                    
                            System.out.println("快速客户"+num+"号等待服务");
                        }                    
                        }            
                    } ,
                    0, 
                    4,
                    TimeUnit.SECONDS
                    );
            Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
                    new Runnable(){         
                        public void run() {
                            Integer num = Numbermachinery.getInstance().vipNumber().numberGenerate(); 
                        if(num!=null){                    
                            System.out.println("VIP客户"+num+"号等待服务");
                        }                    
                        }            
                    } ,
                    0, 
                    7,
                    TimeUnit.SECONDS
                    );    

    }
}