天天看點

張孝祥老師銀行系統案例

package yinghangxitong;

import java.util.concurrent.Executors;

import java.util.concurrent.TimeUnit;

public class MainClass {  

// 用for循環建立出4個普通視窗,再建立出1個快速視窗和一個VIP視窗。

//接着在建立三個定時器,分别定時去建立新的普通客戶号碼、新的快速客戶号碼、新的VIP客戶号碼

    public static void main(String[] args) {  

        for(int i=1;i<5;i++){  

        //建立四個普通視窗,模拟普通視窗  

        ServiceWindow commonwindow=new ServiceWindow();  

        //設定指定視窗的ID  

        commonwindow.setWindowid(i);  

        commonwindow.start();  

        }  

        //建立一個vip視窗  

        ServiceWindow vipwindow=new ServiceWindow();  

        vipwindow.setType(CustomerType.VIP);  

        vipwindow.start();  

        //快速視窗  

        ServiceWindow expresswindow=new ServiceWindow();  

        expresswindow.setType(CustomerType.EXPRESS);  

        expresswindow.start();  

        //開啟三個線程,模拟三個視窗  

        Executors.newScheduledThreadPool(1).scheduleAtFixedRate(new Runnable() {  

            @Override  

            public void run() {  

                //産生模拟的新客戶  

             Integer number=NumberMachine.getInstance().getExpressManager().generateNewManager();  

             System.out.println("第"+number+"号快速客戶在等待服務");  

            }  

        },  

                0,  

                Constants.COMMON_CUSTOMER_Time*2,   //執行間隔  

            TimeUnit.SECONDS);  

    Executors.newScheduledThreadPool(1).scheduleAtFixedRate(new Runnable() {  

        @Override  

        public void run() {  

         Integer number=NumberMachine.getInstance().getVipManager().generateNewManager();  

         System.out.println("第"+number+"号VIP客戶在等待服務");  

        }  

    },  

            0,  

            Constants.COMMON_CUSTOMER_Time*6,  

        TimeUnit.SECONDS);  

Executors.newScheduledThreadPool(1).scheduleAtFixedRate(new Runnable() {  

        @Override  

        public void run() {  

       Integer number=NumberMachine.getInstance().getCommonManager().generateNewManager();  

             System.out.println("第"+number+"号普通客戶在等待服務");  

        }  

    },  

            0,  

            Constants.COMMON_CUSTOMER_Time,  

        TimeUnit.SECONDS);  

    }  

package yinghangxitong;

import java.util.ArrayList;  

import java.util.List;  

//定義使用者存儲上一個客戶号碼的成員變量和用于存儲所有等待服務的客戶号碼的隊列集合

//定義個産生新号碼的方法和擷取馬上要為之服務的号碼的方法,這兩個方法被不同的線程操作了相同的資料,是以,要進行同步。

//号碼機器對象,負責産生客戶  

public class NumberManager {  

    private int lastNumber=0;  

    //排隊序列  

    private List<Integer> queueNumber=new ArrayList<Integer>();  

    //每次産生一個人加入到list中,現在是第lastNumber為客戶開始服務  

    public synchronized int generateNewManager(){  

        queueNumber.add(++lastNumber);  

        return lastNumber;  

    }  

    //取号碼  

    public synchronized Integer fetchServiceNumber(){  

        if(queueNumber.size()>0){  

            return (Integer)queueNumber.remove(0);  

        }else{  

            return null;  

        }  

    }  

}  

package yinghangxitong;

//定義三個成員變量分别指向三個NumberManager對象,分别表示普通、快速和VIP客戶的号碼管理器,定義三個對應的方法

//來傳回這三個NumberManager對象将NumberMachine類設計成單例。

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;

    }

    // 單例模式,構造方法私有化

    private NumberMachine() {

    }

    public static NumberMachine getInstance() {

        return instance;

    }

    private static NumberMachine instance = new NumberMachine();

}

package yinghangxitong;

 //系統中有三種類型的客戶,是以用定義一個枚舉類,其中定義三個成員分别表示三種類型的客戶。

 //重寫toString方法,傳回類型的中文名稱。這是在後面編寫代碼時重構出來的,剛開始不用考慮

//CustomerType枚舉類

//枚舉類型,覆寫toStirng()方法  

public enum CustomerType {

    COMMON, EXPRESS, VIP;

    @Override

    public String toString() {

        // TODO Auto-generated method stub

        switch (this) {

        case COMMON:

            return "普通";

        case EXPRESS:

            return "快速";

        case VIP:

            return name();

        }

        return null;

    }

}

package yinghangxitong;

import java.util.Random;  

import java.util.concurrent.Executors;  

// 定義一個start方法,内部啟動一個線程,根據服務視窗的類别分别循環調用三個不同的方法

// 定義三個方法分别對三種客戶進行服務,為了觀察運作效果,應詳細列印出其中的細節資訊

//ServiceWindow類

//視窗依次叫号  

public class ServiceWindow {  

    private int windowNum=1;  

    public void setWindowid(int windowid) {  

        this.windowNum = windowid;  

    }  

    public void setType(CustomerType type) {  

        this.type = type;  

    }  

    //根據類型的不同進行叫号  

    private CustomerType type=CustomerType.COMMON;  

    public void start(){  

    //

      Executors.newSingleThreadExecutor().execute(new Runnable() {  

        public void run() {  

            while(true){  

                switch (type) {  

                case COMMON:  

                    commonService();  

                    break;  

                case EXPRESS:  

                    expressService();  

                    break;  

                case VIP:  

                    vipService();  

                    break;  

                }  

            }  

        }});}  

        //普通視窗  

        private void commonService() {  

            String windowName="第"+windowNum+"号"+type+"視窗";  

            System.out.println(windowName+"正在擷取普通任務");  

            //取票  

            Integer serviceNum=NumberMachine.getInstance().getCommonManager().fetchServiceNumber();  

            if(serviceNum!=null){  

                System.out.println(windowName+"開始為第"+serviceNum+"号普通客戶服務");  

                int maxRand=Constants.MAX_SERVICE_TIME - Constants.Min_SERVICE_TIME;//最大的服務時間  

                int serveTime=new Random().nextInt(maxRand)+1+Constants.Min_SERVICE_TIME;  

                try {  

                    Thread.sleep(serveTime);  

                } catch (InterruptedException e) {  

                    // TODO Auto-generated catch block  

                    e.printStackTrace();  

                }  

                System.out.println(windowName+"完成為第"+serviceNum+"号普通客戶服務,總共耗時"  

                                             +serveTime/1000+"秒");  

            }  

            else{  

                System.out.println(windowName+"沒有取得普通任務,正在空閑一秒");  

                try {  

                    Thread.sleep(1000);  

                } catch (InterruptedException e) {  

                    // TODO Auto-generated catch block  

                    e.printStackTrace();  

                }  

            }  

        }  

        //快速視窗  

        private void expressService() {  

            //産生客戶的執行個體,  

            Integer serviceNum=NumberMachine.getInstance().getExpressManager().fetchServiceNumber();  

            String windowName="第"+windowNum+"号"+type+"視窗";  

            System.out.println(windowName+"開始擷取快速任務");  

            if(serviceNum!=null){  

                System.out.println(windowName+"開始為第"+serviceNum+"号快速客戶服務");  

                int serviceTime=Constants.Min_SERVICE_TIME;  

                try {  

                    Thread.sleep(serviceTime);  

                } catch (InterruptedException e) {  

                    // TODO Auto-generated catch block  

                    e.printStackTrace();  

                }  

                System.out.println(windowName+"完成為第"+serviceNum+"号快速客戶服務,總共耗時"+  

      serviceTime/1000+"秒");  

            }  

            else{  

                System.out.println(windowName+"沒有取到快速任務");  

                //沒有任務時,為普通客戶服務  

                commonService();  

            }  

        }  

        private void vipService() {  

            String windowName="第"+windowNum+"号"+type+"視窗";  

            System.out.println(windowName+"正在開始擷取VIP任務");  

            Integer serviceNum=NumberMachine.getInstance().getVipManager().fetchServiceNumber();  

            if(serviceNum!=null){  

                System.out.println(windowName+"開始為第"+serviceNum+"号VIP客戶服務");  

                int maxRand=Constants.MAX_SERVICE_TIME-Constants.Min_SERVICE_TIME;//最大的服務時間  

                int serveTime=new Random().nextInt(maxRand)+1+Constants.Min_SERVICE_TIME;  

                try {  

                    Thread.sleep(serveTime);  

                } catch (InterruptedException e) {  

                    // TODO Auto-generated catch block  

                    e.printStackTrace();  

                }  

              System.out.println(windowName+"完成為第"+serviceNum+"号VIP客戶服務,總共耗時"+  

                                         serveTime/1000+"秒");  

            }  

            else{  

                System.out.println(windowName+"沒有取到VIP任務!");//傳遞此時的type,  

  //是以執行commonService()時還是VIP格式類型還是--->第1号VIP視窗開始為第5号普通客戶服務  

                commonService();  

            }  

        }  

    }  

package yinghangxitong;

public class Constants {

    // 定義三個常量:MAX_SERVICE_TIME, MIN_SERVICE_TIME, COMMON_CUSTOMER_INTEGVAL_TIME,

    // 經常用到的常量

    public static int MAX_SERVICE_TIME = 10000;

    public static int Min_SERVICE_TIME = 1000;

    public static int COMMON_CUSTOMER_Time = 1;

}