은행 스케줄링 시스템 노트

23815 단어 필기
1. 은행 스케줄링 업무 시스템
(1) 수요
1. 은행 안에 6개의 업무 창구가 있는데 1-4번 창구는 일반 창구이고 5번 창구는 빠른 창구이며 6번 창구는 VIP 창구이다.
2. 대응하는 세 가지 유형의 고객이 있다. VIP 고객, 일반 고객, 빠른 고객(예를 들어 전기 요금, 전화 요금 등 업무를 처리하는 고객)이다.
3. 비동기적으로 다양한 유형의 고객을 무작위로 생성하고 다양한 유형의 사용자를 생성할 확률은 다음과 같다.
4. VIP 고객: 일반 고객: 빠른 고객 = 1:6:3.
5. 고객이 업무를 처리하는 데 소요되는 시간은 최대치와 최소치가 있고 이 범위 내에서 모든 VIP 고객과 일반 고객이 업무를 처리하는 데 소요되는 시간을 무작위로 설정하고 신속한 고객이 업무를 처리하는 데 소요되는 시간은 최소치이다(힌트: 업무를 처리하는 과정은 스레드슬립의 방식으로 시뮬레이션할 수 있다).
6. 각 유형의 고객은 해당 창구에서 순서대로 업무를 처리한다. 
7. VIP(6번)창구와 신속업무(5번)창구에 고객이 업무 처리를 기다리지 않을 경우 이 두 창구는 일반 고객의 업무를 처리할 수 있고, 대응하는 고객이 업무 처리를 기다리고 있을 때 대응하는 고객의 업무를 우선적으로 처리한다.
8. 랜덤으로 고객의 시간 간격과 업무 처리 시간의 최대치와 최소치를 생성하여 설정할 수 있습니다.
(2) 대상을 대상으로 하는 분석과 디자인
분석 수요 1, 6, 7 알 수 있듯이 서비스 창을 대표하는 클래스가 필요하고 이 클래스는 하나의 속성이 있어야 한다. 창의 번호와 창 서비스 대상 유형을 대표하는 속성이 있어야 한다.서비스 창구는 서로 다른 서비스 대상이 있고 각 서비스의 수요도 다르기 때문에 세 가지 서비스 방법으로 일반 사용자, 빠른 사용자, VIP 사용자를 각각 서비스해야 한다.창구에서 한 대상을 서비스한 후에 만약에 다음에 서비스를 기다리는 대상이 있다면 창구는 계속 서비스를 해야 하기 때문에 하나의 라인이 끊임없이 서비스 대상을 얻는 것을 정의해야 한다. 그리고 만약에 빠른 창구와 VIP 창구라면 빠른 업무나 VIP 업무가 완료되면 일반 고객에게 계속 서비스를 제공해야 한다.그래서 시작 방법을 정의하고 하나의 프로세스 탱크를 정의하며 서로 다른 고객에 따라 서로 다른 서비스 코드를 집행한다. 구체적인 수요는 다음과 같다. 일반 고객 서비스 코드, 획득 대상, 대상이 있으면 그 서비스를 위해 끝나고 다시 호출하는 방법이다. 없으면 1초 동안 휴식을 취한 다음에 대상의 빠른 고객 서비스 코드, 획득 대상,대상이 있으면 그 서비스를 위해 종료한 후에 다시 방법을 호출한다. 대상이 없으면 일반 고객 대상을 획득하고 일반 고객 서비스를 위해 서비스 시간은 1초 VIP 고객 서비스 코드로 고정하고 대상을 획득한다. 대상이 있으면 그 서비스를 위해 종료한 후에 다시 호출한다. 대상이 없으면 일반 고객 대상을 획득한다.일반 고객 서비스를 위해 프로그램에 사용되는 상수를 단독 클래스에 정의하고, 하나의 매거 클래스를 따로 정의하며, 고객 유형을 저장하고, toString () 방법을 복사합니다.세 가지 유형의 고객이 있는데 그것이 바로 VIP 고객, 일반 고객, 빠른 고객, 비동기적으로 각종 유형의 고객을 무작위로 생성하고 각종 유형의 고객은 대응하는 창에서 순서대로 업무를 처리한다.각 유형의 고객은 대응하는 창구에서 순서대로 업무를 처리하는데 정확히 말하면 창구에서 순서대로 번호를 불러야 한다.각 창구에서 어떤 번호로 불러야 하는지 어떻게 알아요?그는 반드시 상응하는 번호 관리자, 즉 서비스 창이 매번 번호 관리자를 찾아 현재 서비스될 번호를 얻는 것을 물어야 한다.
서비스 창 클래스의 코드는 다음과 같습니다.
package cn.itcast.bankqueue;



import java.util.Random;



import java.util.concurrent.Executors;



import java.util.logging.Logger;



/**



 *    VIP           ,                     VIP       。



 * */



public class ServiceWindow {



private static Logger logger = Logger.getLogger("cn.itcast.bankqueue");



private CustomerType type = CustomerType.COMMON;



private int number = 1;



 



public CustomerType getType() {



  return type;



}



 



public void setType(CustomerType type) {



this.type = type;



}



 



public void setNumber(int number){



this.number = number;



}



 



public void start(){



Executors.newSingleThreadExecutor().execute(



new Runnable(){



public void run(){



//            ,    while  case  



while(true){



switch(type){



case COMMON:



commonService();



break;



case EXPRESS:



expressService();



break;



case VIP:



vipService();



break;



}



}



}



}



);



}



 



private void commonService(){



String windowName = " " + number + " " + type + "  ";



System.out.println(windowName + "        !");



Integer serviceNumber = NumberMachine.getInstance().getCommonManager().fetchNumber();



if(serviceNumber != null ){



System.out.println(windowName + "    " + serviceNumber + "       ");



int maxRandom = Constants.MAX_SERVICE_TIME - Constants.MIN_SERVICE_TIME;



int serviceTime = new Random().nextInt(maxRandom)+1 + Constants.MIN_SERVICE_TIME;



 



try {



Thread.sleep(serviceTime);



} catch (InterruptedException e) {



e.printStackTrace();



}



System.out.println(windowName + "    " + serviceNumber + "       ,    " + serviceTime/1000 + " ");



}else{



System.out.println(windowName + "        ,      ");



try {



Thread.sleep(1000);



} catch (InterruptedException e) {



e.printStackTrace();



}



}



}



 



private void expressService(){



Integer serviceNumber = NumberMachine.getInstance().getExpressManager().fetchNumber();



String windowName = " " + number + " " + type + "  ";



System.out.println(windowName + "        !");



if(serviceNumber !=null){



System.out.println(windowName + "    " + serviceNumber + "       ");



int serviceTime = Constants.MIN_SERVICE_TIME;



try {



Thread.sleep(serviceTime);



} catch (InterruptedException e) {



e.printStackTrace();



}



System.out.println(windowName + "    " + serviceNumber + "       ,    " + serviceTime/1000 + " ");



}else{



System.out.println(windowName + "        !");



commonService();



}



}



 



private void vipService(){



 



Integer serviceNumber = NumberMachine.getInstance().getVipManager().fetchNumber();



String windowName = " " + number + " " + type + "  ";



System.out.println(windowName + "    VIP  !");



if(serviceNumber !=null){



System.out.println(windowName + "    " + serviceNumber + " VIP    ");



int maxRandom = Constants.MAX_SERVICE_TIME - Constants.MIN_SERVICE_TIME;



int serviceTime = new Random().nextInt(maxRandom)+1 + Constants.MIN_SERVICE_TIME;



try {



Thread.sleep(serviceTime);



} catch (InterruptedException e) {



e.printStackTrace();



}



System.out.println(windowName + "    " + serviceNumber + " VIP    ,    " + serviceTime/1000 + " ");



}else{



System.out.println(windowName + "    VIP  !");



commonService();



}



}



}

 
분석 수요2에서 알 수 있듯이 세 가지 다른 고객 유형이 있기 때문에 하나의 매거 유형의 대상을 정의해야 한다. 그리고 이 대상은 toString()을 복사해서 외부에 그 고객이 그런 고객이라는 것을 알려야 한다. CustomerType 종류의 코드는 다음과 같다.
package cn.itcast.bankqueue;



 



public enum CustomerType {



COMMON,EXPRESS,VIP;



//  toString()



public String toString(){



String name = null;



switch(this){



case COMMON:



name = "  ";



break;



case EXPRESS:



name = "  ";



break;



case VIP:



name = name();



break;



}



return name;



}



}

서비스를 받으러 온 고객이 한 명만 있는 것이 아니기 때문에 서로 다른 고객에게 서로 다른 정렬 번호를 만들어야 하기 때문에 번호 관리자 대상인 NumberManager 클래스가 필요합니다. 이 대상은 새로운 번호를 만들 수도 있고 다음 줄의 번호를 얻을 수도 있습니다.
NumberManager 클래스는 콜아웃 기능을 수행하여 대기열에 번호를 추가합니다.대기열의 번호 수가 0보다 크면, 대기열의 첫 번째 번호를 꺼냅니다. List 집합과 그 번호의remove () 를 사용합니다. 지정한 위치의 요소를 제거하고, 제거된 요소를 되돌려줍니다.다중 스레드이기 때문에 스레드의 안전을 고려해야 한다. 즉, 스레드가 동기화되어야 하기 때문에synchronized를 추가한다.
번호 관리자 클래스 코드는 다음과 같습니다.
package cn.itcast.bankqueue;



 



import java.util.ArrayList;



import java.util.List;



 



public class NumberManager {



 



private int lastNumber = 0;



private List queueNumbers = new ArrayList();



 



public synchronized Integer generateNewNumber(){



queueNumbers.add(++lastNumber);



return lastNumber;



}



 



public synchronized Integer fetchNumber(){



if(queueNumbers.size()>0){



return (Integer)queueNumbers.remove(0);



}else{



return null;



}



}



}

고객 유형을 대표하는 대상과 번호 관리자가 있지만 아직 이런 유형의 방법이 생기지 않았기 때문에 고객 대상을 전문적으로 생성하는 클래스, 즉 고객을 대표하는 번호 기계인 NumberMachine 클래스를 정의해야 한다. 세 가지 고객이 있기 때문에 각 유형의 고객의 번호 배열은 완전히 독립적이기 때문에이 시스템은 모두 세 개의 번호 관리자 대상을 만들어 각각 한 종류의 사용자의 줄 서기 번호를 관리해야 한다고 생각한다.이 세 개의 번호 관리자 대상은 통일적으로 번호 기계가 관리한다. 이 번호 기계는 전체 시스템에서 하나만 있을 수 있기 때문에 이것은 단일 모델로 설계되어야 한다.NumberMachine 클래스의 코드는 다음과 같습니다.
package cn.itcast.bankqueue;



 



public class NumberMachine {



 



private NumberMachine(){}



private static NumberMachine instance = new NumberMachine();



public static NumberMachine getInstance(){



return instance;



}



 



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;



}



 



}

수요 4, 5, 8에서 알 수 있듯이 매번 얼마마다 새로운 고객이 발생하는 시간과 업무 처리의 최대 시간과 최소 시간을 규정해야 한다.여기에는 Constants 클래스가 표시됩니다.만약에 모든 일반 창구에서 한 고객에게 서비스를 제공하는 평균 시간이 5초라고 가정하면 모두 4개의 이런 창구가 있다. 즉, 은행의 모든 일반 창구를 합치면 평균 1.25초 안에 한 명의 일반 고객을 서비스할 수 있고 게다가 빠른 창구와 VIP 창구도 일반 고객을 서비스할 수 있기 때문에 1초 안에 일반 고객을 생성하는 것이 합리적이다.따라서 Constants 클래스의 코드는 다음과 같습니다.
package cn.itcast.bankqueue;



 



public class Constants {



public static int MAX_SERVICE_TIME = 10000; //10 !



public static int MIN_SERVICE_TIME = 1000; //1 !



 



/*                  5 ,   4      ,                



 *   1.25             ,        VIP           ,  ,



 * 1              ,*/



public static int COMMON_CUSTOMER_INTERVAL_TIME = 1; 



}

(3) 은행 업무 스케줄링 시스템 가동
제목에 따라 시작할 때 4개의 일반 창, 1개의 빠른 창, 1개의 VIP 창을 생성하고 창의 start() 방법을 호출하여 해당하는 고객을 얻고 해당하는 고객을 얻으면 서비스를 제공한다.동시에 스레드 탱크를 구축하고 고객 비율(1:6:3)에 따라 해당하는 타이머 간격을 설정하여 고객을 생성한다.
MainClass 클래스의 코드는 다음과 같습니다.
package cn.itcast.bankqueue;



import java.util.concurrent.Executors;



import java.util.concurrent.TimeUnit;



import java.util.logging.Logger;



 



public class MainClass {



 



private static Logger logger = Logger.getLogger("cn.itcast.bankqueue");



 



 



public static void main(String[] args) {



//  4     



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



ServiceWindow window =  new ServiceWindow();



window.setNumber(i);



window.start();



}



 



//  1     



ServiceWindow expressWindow =  new ServiceWindow();



expressWindow.setType(CustomerType.EXPRESS);



expressWindow.start();



 



//  1 VIP  



ServiceWindow vipWindow =  new ServiceWindow();



vipWindow.setType(CustomerType.VIP);



vipWindow.start();



 



//      



Executors.newScheduledThreadPool(1).scheduleAtFixedRate(



new Runnable(){



public void run(){



Integer serviceNumber = NumberMachine.getInstance().getCommonManager().generateNewNumber();



/**



 *   logger  ,           ,  logger.log                 ,



 *               ,  ,                   。



 */



//logger.info(" " + serviceNumber + "           !");



System.out.println(" " + serviceNumber + "           !");



}



},



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 + "           !");



}



},



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        !");



}



},



0,



Constants.COMMON_CUSTOMER_INTERVAL_TIME * 6, 



TimeUnit.SECONDS);



}



 



}

(4) 총결산
이 프로젝트에서 저는 대상을 대상으로 하는 것, 매거진, 집합, 단일 디자인 모델, 스레드 탱크와 스레드 안전(즉 스레드 동기화synchronized)과 수요 분석 등 고급 지식을 많이 배웠습니다. 대상을 대상으로 말하자면 이 프로젝트는 이 말을 다시 한 번 검증했습니다. 데이터를 가진 사람이 대외적으로 이 데이터를 조작하는 방법을 제공하는 것입니다.이 프로젝트와 이전의 교통등 프로젝트는 모두 상기 고급 지식을 사용했기 때문에 저는 그것들에 대한 이해를 다시 한 번 깊이 있게 하고 앞으로 그것들을 능숙하게 활용하기 위해 기초를 다졌습니다.

좋은 웹페이지 즐겨찾기