java项目--银行调度系统


首先定义
号码管理类
要有取号的方法,将号码加入到集合中去
要有得到号码的方法。(每次取出集合中的第一个)
都是多线程操作,所以要synchronized

public class NumberManager {

 private int lastNumber = 0;
 private List queueNumber = new ArrayList();

 public synchronized int generateNewManager() {
  lastNumber = lastNumber + 1;
  queueNumber.add(lastNumber);
  return lastNumber;
 }

 public synchronized Integer fetchServiceNumber()// 这里用int的话,如果集合为空的时候remove(0)就会返回一个空,就会出现空指针异常
 {
  Integer number = null;
  if (queueNumber.size() > 0) {
   number = queueNumber.remove(0);// 从集合中取出第一个数字,也就是排队的第一个
  }
  return number;
 }
}

第二,要有一个号码机器类
产生3种号码管理。new出三个号码管理,并且可以得到这三个对象
只有一个号码机器提供号码,所以要是单例模式

public class NumberMachine {
 private 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 static NumberMachine instance = new NumberMachine();

 public static NumberMachine getInstance() {
  return instance;
 }
}


第三写一个服务窗口类
要有一个窗口类型的属性,有赋给的方法

要有一个开始(start)方法:有一个线程池
      判断是哪种类型的客户给出不同的服务

普通服务的方法:从号码机器得到普通的号码管理,取得普通号码
   得到  ?开始服务,到结束服务,在执行start方法
   没得到?休息一秒,在次执行start方法

快速服务的方法:
VIP服务的方法;
   从号码机器得到相应的号码管理,取得相应号码
   得到  ?开始服务,到结束服务,在执行start方法
   没得到?直接执行普通服务方法

 

public class ServiceWindow {

 private CustomerType type = CustomerType.COMMON;
 private int windowId = 1;

 public void setType(CustomerType type) {
  this.type = type;
 }

 public void setWindowId(int windowId) {
  this.windowId = windowId;
 }

 public void start() {
  // 线程池
  Executors.newSingleThreadExecutor().execute(new Runnable() {
   public void run() {// switch效率要比if else高
    switch (type) {
    case COMMON:
     commonService();
     break;
    case EXPRESS:
     expressService();
     break;
    case VIP:
     vipService();
     break;
    }
   }
  });
 }

 private void commonService() {
  String windowName = "第 " + windowId + " 号 " + type + " 窗口";
  Integer number = NumberMachine.getInstance().getCommonManager()
    .fetchServiceNumber();
  System.out.println(windowName + " 开始获取 普通 任务");
  if (number != null) {
   System.out.println(windowName + " 为第 " + number + " 号 普通 客户服务");
   long beginTime = System.currentTimeMillis();

   long serverTime = Constants.MIN_SERVICE_TIME
     + ((int) (Math.random()
       * (Constants.MAX_SERVICE_TIME - Constants.MIN_SERVICE_TIME) + 1));
   try {
    Thread.sleep(serverTime);
   } catch (InterruptedException e) {
    e.printStackTrace();
   }
   long endTime = System.currentTimeMillis();

   System.out.println(windowName + " 为第 " + number + " 号客户服务,耗时 "
     + (endTime - beginTime) / 1000 + " 秒");
   start();
  } else {
   System.out.println(windowName + " 没有取到 普通 任务,空闲一秒");
   try {
    Thread.sleep(1000);
    start();// 这里可以在start方法中写一个循环,就不用加了
   } catch (InterruptedException e) {
    e.printStackTrace();
   }
  }
 }

 private void expressService() {
  String windowName = "第 " + windowId + " 号 " + type + " 窗口";
  Integer number = NumberMachine.getInstance().getExpressManager()
    .fetchServiceNumber();
  System.out.println(windowName + " 开始获取 快速 任务");
  if (number != null) {
   System.out.println(windowName + " 为第 " + number + " 号 快速 客户服务");
   long beginTime = System.currentTimeMillis();

   long serverTime = Constants.MIN_SERVICE_TIME;
   try {
    Thread.sleep(serverTime);
   } catch (InterruptedException e) {
    e.printStackTrace();
   }
   long endTime = System.currentTimeMillis();

   System.out.println(windowName + " 为第 " + number + " 号客户服务,耗时 "
     + (endTime - beginTime) / 1000 + " 秒");
   start();
  } else {
   System.out.println(windowName + " 没有取到取 快速 任务,获取 普通 任务");
   commonService();
  }
 }

 private void vipService() {
  String windowName = "第 " + windowId + " 号 " + type + " 窗口";
  Integer number = NumberMachine.getInstance().getVipManager()
    .fetchServiceNumber();
  System.out.println(windowName + " 开始获取 vip 任务");
  if (number != null) {
   System.out.println(windowName + " 为第 " + number + " 号 vip 客户服务");
   long beginTime = System.currentTimeMillis();

   long serverTime = Constants.MIN_SERVICE_TIME
     + ((int) (Math.random()
       * (Constants.MAX_SERVICE_TIME - Constants.MIN_SERVICE_TIME) + 1));
   try {
    Thread.sleep(serverTime);
   } catch (InterruptedException e) {
    e.printStackTrace();
   }
   long endTime = System.currentTimeMillis();

   System.out.println(windowName + " 为第 " + number + " 号客户服务,耗时 "
     + (endTime - beginTime) / 1000 + " 秒");
   start();
  } else {
   System.out.println(windowName + " 没有取到 vip 任务,获取 普通 任务");
   commonService();
  }
 }
}


第四写一个主类
创建4个普通窗口,开始工作,start();
创建1个快速窗口,开始工作,start();
创建1个VIP窗口,开始工作,start();

开启三个定时器,分别以不同的速度来不同的客户

public class MainClass {
 public static void main(String[] args){
  for(int i=1;i<=4;i++)
  {
   ServiceWindow commonWindow=new ServiceWindow();
   commonWindow.setWindowId(i);
   commonWindow.setType(CustomerType.COMMON);
   commonWindow.start();
  }
  
  ServiceWindow expressWindow=new ServiceWindow();
  expressWindow.setWindowId(5);
  expressWindow.setType(CustomerType.EXPRESS);
  expressWindow.start();
  
  ServiceWindow vipWindow=new ServiceWindow();
  vipWindow.setWindowId(6);
  vipWindow.setType(CustomerType.VIP);
  vipWindow.start();
  
  //定时器
  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);
  
  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().getExpressManager().generateNewManager();
      System.out.println(number+" 号 快速 客户等待服务");
     }
    },
    0,
    Constants.COMMON_CUSTOMER_TIME*2,//这个地方为什么是2,很绕,绕了好久,
    //一秒钟可以进来一个(6/10)的那一类人,那么2秒中可以进来一个(3/10)的那一类人,6秒中可以进来一个(1/10)的那一类人
    TimeUnit.SECONDS);
 }
}

最后将程序中的所要使用的类型定义成单个类,将服务最大最小时间也封装成一个类

public enum CustomerType {
 COMMON,EXPRESS,VIP;
 
 public String toString()
 {
  switch (this) {
  case COMMON:
   return "普通";
  case EXPRESS:
   return "快速";
  case VIP:
   return name();
  }
  return null;
 }
}

public class Constants {
 public static int MAX_SERVICE_TIME=10000;
 public static int MIN_SERVICE_TIME=1000;
 public static int COMMON_CUSTOMER_TIME=1;
}

总结:这个实战型项目,运用了很多可以java基础知识。java的多线程,要使用同步函数synchronized,来避免多线程下的错误。
在号码机器类中使用了单例模式,让所有的号码都是有同一个号码机器产生的。在服务窗口中通过switch判断号码类型给以不同的
服务。在服务方法中,如果取到要服务的客户,那么为其服务,并记录下服务的时间,没有取到就执行等待后重复start方法,或者
直接执行普通服务的方法。在主类中使用了定时器,每种客户来的速度不同,设置定时器的刷新时间。
同样很巧妙的使用了面相对象编程,java就是一门面相对象编程的语言。这个是以后要多练习的。

 

复习时看着这个图就能很轻松的写下代码


你可能感兴趣的:(java基础日记,java,integer,service,express,任务)