题目如下:
/* 模拟实现银行业务调度系统逻辑,具体需求如下: 银行内有6个业务窗口,1 - 4号窗口为普通窗口,5号窗口为快速窗口,6号窗口为VIP窗口。 有三种对应类型的客户:VIP客户,普通客户,快速客户(办理如交水电费、电话费之类业务的客户)。 异步随机生成各种类型的客户,生成各类型用户的概率比例为: VIP客户:普通客户:快速客户 = 1 :6 :3。 客户办理业务所需时间有最大值和最小值,在该范围内随机设定每个VIP客户以及普通客户办理业务所需的时间,快速客户办理业务所需时间为最小值(提示:办理业务的过程可通过线程Sleep的方式模拟)。 各类型客户在其对应窗口按顺序依次办理业务。 当VIP(6号)窗口和快速业务(5号)窗口没有客户等待办理业务的时候,这两个窗口可以处理普通客户的业务,而一旦有对应的客户等待办理业务的时候,则优先处理对应客户的业务。 随机生成客户时间间隔以及业务办理时间最大值和最小值自定,可以设置。 不要求实现GUI,只考虑系统逻辑实现,可通过打印的方式展现程序运行结果。 */方案一:
Customer.java 本源文件定义了三种客户,以及枚举类型的客户类型。
package banktellersimulation; enum CUSTOMER{ VIP, //1 ORDINARY, //6 QUICK //3 } public class Customer { private final CUSTOMER id; private final int servicetime; public Customer(CUSTOMER customer){ if (customer == CUSTOMER.VIP){ servicetime = 500; } else if (customer == CUSTOMER.ORDINARY){ servicetime = 300; } else { servicetime = 100; } id = customer; } public int getServiceTime(){ return servicetime; } public String toString(){ return id.toString() + ":" + getServiceTime(); } }CustomerGenerator.java是一个生产者模型,即向相应的容器中添加客户——消费者。
package banktellersimulation; import java.util.ArrayList; import java.util.Random; import java.util.concurrent.ArrayBlockingQueue; import com.sun.org.apache.xalan.internal.xsltc.compiler.sym; public class CustomerGenerator implements Runnable{ private ArrayBlockingQueue<Customer> customerlinevip; private ArrayBlockingQueue<Customer> customerlineoridinary; private ArrayBlockingQueue<Customer> customerlinequick; private Random rand = new Random(); private double[] data = new double[]{0.0, 0.1, 0.7, 1.0}; public CustomerGenerator(ArrayBlockingQueue<Customer> customerlinevip, ArrayBlockingQueue<Customer> customerlineoridinary, ArrayBlockingQueue<Customer> customerlinequick) { super(); this.customerlinevip = customerlinevip; this.customerlineoridinary = customerlineoridinary; this.customerlinequick = customerlinequick; } @Override public void run() { while(!Thread.interrupted()){ int i = 0; double temp = rand.nextDouble(); for (i = 0; i < data.length - 1; i++){ if (temp >= data[i] && temp < data[i + 1]){ break; } } switch (CUSTOMER.values()[i]){ case VIP: try { customerlinevip.put(new Customer(CUSTOMER.VIP)); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } break; case ORDINARY: try { customerlineoridinary.put(new Customer(CUSTOMER.ORDINARY)); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } break; case QUICK: try { customerlinequick.put(new Customer(CUSTOMER.QUICK)); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } break; default: } } } }
package banktellersimulation; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.TimeUnit; public class Window implements Runnable{ private final int id; private ArrayBlockingQueue<Customer> customerlinevip; private ArrayBlockingQueue<Customer> customerlineoridinary; private ArrayBlockingQueue<Customer> customerlinequick; public Window(int id, ArrayBlockingQueue<Customer> customerlinevip, ArrayBlockingQueue<Customer> customerlineoridinary, ArrayBlockingQueue<Customer> customerlinequick){ this.customerlinevip = customerlinevip; this.customerlineoridinary = customerlineoridinary; this.customerlinequick = customerlinequick; this.id = id; } @Override public void run() { try{ while (!Thread.interrupted()){ Customer temp = null; if (id >= 1 && id <= 4){ temp = customerlineoridinary.take(); TimeUnit.MICROSECONDS.sleep(temp.getServiceTime()); } else if (id == 5){ if (customerlinequick.size() == 0 && customerlineoridinary.size() != 0){ temp = customerlineoridinary.take(); TimeUnit.MICROSECONDS.sleep(temp.getServiceTime()); } else { temp = customerlinequick.take(); TimeUnit.MICROSECONDS.sleep(temp.getServiceTime()); } } else if (id == 6){ if (customerlinevip.size() == 0 && customerlineoridinary.size() != 0){ temp = customerlineoridinary.take(); TimeUnit.MICROSECONDS.sleep(temp.getServiceTime()); } else { temp = customerlinevip.take(); TimeUnit.MICROSECONDS.sleep(temp.getServiceTime()); } } System.out.println(temp + "deal by:" + this); } }catch (InterruptedException e) { e.printStackTrace(); } } public String toString(){ return id + ""; } }
package banktellersimulation; import java.util.concurrent.ArrayBlockingQueue; public class Bank { public static void main(String[] args){ ArrayBlockingQueue<Customer> customerlinevip = new ArrayBlockingQueue<Customer>(20); ArrayBlockingQueue<Customer> customerlineoridinary = new ArrayBlockingQueue<Customer>(20); ArrayBlockingQueue<Customer> customerlinequick = new ArrayBlockingQueue<Customer>(20); new Thread(new CustomerGenerator(customerlinevip, customerlineoridinary, customerlinequick)).start(); for (int i = 1; i <=6 ;i++){ new Thread(new Window(i, customerlinevip, customerlineoridinary, customerlinequick)).start(); } } }
方案二:模拟银行的行为,下边的代码不是本人编写,但是编写的确高,特列写如下:
Constants.java,这个源文件里面定义了一些常量,主要是模拟服务时间的长短设置
package com.hzgg.demo; public class Constants { //服务的最小时间 public static final int MIN_SERVICE_TIME = 1000; //服务的最大时间 public static final int MAX_SERVICE_TIME = 10000; }
package com.hzgg.demo; public enum CustomerType { COMMON, EXPRESS, VIP; public String toString() { switch (this) { case COMMON: return "普通"; case EXPRESS: return "快速"; case VIP: return "VIP"; } return null; } }
package com.hzgg.demo; import java.util.ArrayList; import java.util.List; /* * 号码管理器 */ public class NumberManager { private Integer nextNumber = 1; private List<Integer> numberQueue = new ArrayList<Integer>(); /* * 获取下一个号码 */ public synchronized Integer getGenerateNewNumber() { numberQueue.add(nextNumber); return nextNumber++; } /* * 叫号/获取下一个服务号 */ public synchronized Integer fetchServiceNumber(){ Integer number = null; if(numberQueue.size() > 0){ number = numberQueue.remove(0); } return number; } }
package com.hzgg.demo; /* * 取号机 */ public class NumberMachine { private NumberManager commonManager = new NumberManager(); //普通号码生成器 private NumberManager expressManager = new NumberManager(); //快速号码生成器 private NumberManager vipManager = new NumberManager(); //VIP号码生成器 private static NumberMachine instance = new NumberMachine(); private NumberMachine() { } public static NumberMachine getInstance() { return instance; } /* * 取普通客户号码管理器 */ public NumberManager getCommonManager() { return commonManager; } /* * 取快速客户号码管理器 */ public NumberManager getExpressManager() { return expressManager; } /* * 取VIP客户号码管理器 */ public NumberManager getVipManager() { return vipManager; } }
package com.hzgg.demo; /* * 客户生成管理器 */ public class CustomerManager extends Thread { private NumberMachine numberMachine; private NumberManager commonManager; private NumberManager expressManager; private NumberManager vipManager; private CustomerType type; private long time; public CustomerManager(CustomerType type, long time) { this.type = type; this.time = time; numberMachine = NumberMachine.getInstance(); commonManager = numberMachine.getCommonManager(); expressManager = numberMachine.getExpressManager(); vipManager = numberMachine.getVipManager(); } public void run() { while (true) { Integer number = null; switch (type) { case COMMON: number = commonManager.getGenerateNewNumber(); System.out.println(number + "号普通客户等待服务"); break; case EXPRESS: number = expressManager.getGenerateNewNumber(); System.out.println(number + "号快速客户等待服务"); break; case VIP: number = vipManager.getGenerateNewNumber(); System.out.println(number + "号VIP客户等待服务"); break; default: } try { Thread.sleep(time); } catch (InterruptedException e) { e.printStackTrace(); } } } }
package com.hzgg.demo; import java.util.Random; /* * 服务窗口 */ public class ServiceWindow extends Thread { private NumberMachine numberMachine; private NumberManager commonManager; private NumberManager expressManager; private NumberManager vipManager; private Random rn = new Random(); private int windowId; // 窗口号 private CustomerType type = CustomerType.COMMON; public ServiceWindow() { numberMachine = NumberMachine.getInstance(); commonManager = numberMachine.getCommonManager(); expressManager = numberMachine.getExpressManager(); vipManager = numberMachine.getVipManager(); } /* * 窗口开始服务 */ public void run() { while (true) { switch (type) { case COMMON: commonService(); break; case EXPRESS: expressService(); break; case VIP: vipService(); break; default: } } } /* * 普通客户服务 */ private void commonService() { System.out.println("第" + windowId + "号" + type + "窗口开始普通服务"); // 开始获取服务号 Integer number = commonManager.fetchServiceNumber(); if (number != null) { // 开始服务 System.out.println("第" + windowId + "号" + type + "窗口正在为" + number + "号普通客户服务"); long beginTime = System.currentTimeMillis();// 服务开始时间 int maxRand = Constants.MAX_SERVICE_TIME - Constants.MIN_SERVICE_TIME; long serviceTime = rn.nextInt(maxRand) + Constants.MIN_SERVICE_TIME; // 服务时间 try { Thread.sleep(serviceTime); } catch (InterruptedException e) { e.printStackTrace(); } long endTime = System.currentTimeMillis(); // 服务结束时间 long costTime = endTime - beginTime;// 服务所花时间 System.out.println("第" + windowId + "号" + type + "窗口为" + number + "号普通客户服务完成,所花时间为" + costTime / 1000); } else { // 没有客户,等待 System.out.println("第" + windowId + "号" + type + "窗口没有客户,休息1秒"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } /* * 快速客户服务 */ private void expressService() { System.out.println("第" + windowId + "号" + type + "窗口开始服务"); Integer number = expressManager.fetchServiceNumber(); if (number != null) { // 开始服务 System.out.println("第" + windowId + "号" + type + "窗口正在为" + number + "号快速客户服务"); try { Thread.sleep(Constants.MIN_SERVICE_TIME); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("服务所花时间为" + Constants.MIN_SERVICE_TIME / 1000); } else { // 没有客户,处理普通用户 commonService(); } } /* * VIP客户服务 */ private void vipService() { System.out.println("第" + windowId + "号" + type + "窗口开始服务"); // 开始获取服务号 Integer number = vipManager.fetchServiceNumber(); if (number != null) { // 开始服务 System.out.println("第" + windowId + "号" + type + "窗口正在为" + number + "号VIP客户服务"); long beginTime = System.currentTimeMillis();// 服务开始时间 int maxRand = Constants.MAX_SERVICE_TIME - Constants.MIN_SERVICE_TIME; long serviceTime = rn.nextInt(maxRand) + Constants.MIN_SERVICE_TIME; // 服务时间 try { Thread.sleep(serviceTime); } catch (InterruptedException e) { e.printStackTrace(); } long endTime = System.currentTimeMillis(); // 服务结束时间 long costTime = endTime - beginTime;// 服务所花时间 System.out.println("服务所花时间为" + costTime / 1000); } else { // 没有客户,处理普通用户 commonService(); } } public void setType(CustomerType type) { this.type = type; } public void setWindowId(int windowId) { this.windowId = windowId; } }
package com.hzgg.demo; public class MainClass { public static void main(String[] args) { //4个普通窗口 for(int i=1;i<5;i++){ ServiceWindow commWin = new ServiceWindow(); commWin.setWindowId(i); commWin.start(); } //1个快速窗口 ServiceWindow expWin = new ServiceWindow(); expWin.setType(CustomerType.EXPRESS); expWin.setWindowId(5); expWin.start(); //1个VIP窗口 ServiceWindow vipWin = new ServiceWindow(); vipWin.setType(CustomerType.VIP); vipWin.setWindowId(6); vipWin.start(); //生成客户 CustomerManager commonCustomer = new CustomerManager(CustomerType.COMMON, 1000); //1秒种生成一个 commonCustomer.start(); CustomerManager expressCustomer = new CustomerManager(CustomerType.EXPRESS, 2000); //2秒种生成一个 expressCustomer.start(); CustomerManager vipCustomer = new CustomerManager(CustomerType.VIP, 6000); //6秒种生成一个 vipCustomer.start(); } }
代码纯粹个人编写(方案一),水平有限如果有什么错误,欢迎大家扶正。