第一个类:号码枚举类- import java.util.*;
- /**
- * 因为取号程序只有3个,所以设置为枚举对象
- *
- * 取号程序应该有以下方法:
- * 1、产生号码的方法(客户拿号)
- * 2、获取号码的方法(窗口拿号)
- * 3、判断是否还有号码在排除
- *
- * @author Administrator
- *
- */
- public enum NumberManager {
- VIP, COMMON, EXPRESS; // 三个取号程序
- private List<Integer> numberList = new ArrayList<Integer>();// 用来保存生产的号码列表
- private int number;
- private static final int generateTime = 5;// 生成普通号码的时间的最大值
- private NumberManager() {// 启动一个线程用来不停地生产号码
- new Thread(new Runnable() {
- public void run() {
- generateNumber();
- }
- }).start();
- }
- //------------------------1、产生号码的方法(客户拿号)---------------------------------------
- public void generateNumber() {
- for (int i = 1; i < 501; i++) {// 假设每天只有500张排队号码纸
- if (name().equals("COMMON")) // 如果是普通用户则1秒产生一个
- try {Thread.sleep(1000);} catch (Exception e) {e.printStackTrace();}
- else if (name().equals("EXPRESS"))// 如果是快速用户则2~10秒产生一个
- try {Thread.sleep((new Random().nextInt(generateTime) + 1)*1000*2);} catch (Exception e) { e.printStackTrace();}
- else // 如果是VIP用户则6~30秒产生一个
- try {Thread.sleep((new Random().nextInt(generateTime) + 1)*1000*6);} catch (Exception e) { e.printStackTrace();}
- synchronized (COMMON) {
- numberList.add(++number);
- System.out.println(this + "客户 " + number + "号----------->正在等服务");
- }
- }
- }
- //------------------------2、获取号码的方法(窗口拿号)---------------------------------------
- public int getNumber() {
- return ((Integer) numberList.remove(0)).intValue();//拿到号码,并把号码从排除列表中移除
- }
- //------------------------3、判断是否还有号码在排除-------------------------------------------
- public boolean hasNumber() {
- return !numberList.isEmpty();
- }
-
- //------------------------重写toString方法---------------------------------------------------
- public String toString(){
- if(name().equals("COMMON"))
- return "普通";
- else if(name().equals("EXPRESS"))
- return "快速";
- else
- return "VIP";
- }
- }
复制代码 第一个类:业务窗口类- import java.util.Random;
- import java.util.concurrent.*;
- /**
- * 办理业务窗口应该有的方法:
- * 1、判断自己是否在为客户办理业务
- * 2、判断4个普通窗口是否同时都在为客户办理业务
- * 3、去问号码管理器取号,并为对应号码的客户办理业务
- * 4、因为普通窗口有4个,它们处理的都是同样的数据(普通号码)所以,普通窗口取号的代码要进行同步处理
- * 5、因为6个窗口都有处理普通号码的功能,所以可以把处理普通号码的代码单独写成一个方法,以便复用
- * @author Administrator
- *
- */
- public enum ServiceWindows {
- COMMON1, COMMON2, COMMON3, COMMON4, EXPRESS, VIP;//6个办理业务窗口
- private boolean ServiceState;// 指示当前窗口是否在为客户办理业务的状态
- private ServiceWindows() {
- ExecutorService pool = Executors.newSingleThreadExecutor();
- pool.execute(new Runnable(){ //启动一个线程,给拿到号的顾客办理业务
- public void run(){
- while(true){
- getNumber();
- }}});
- }
- //----------------------1、判断自己是否在为客户办理业务 --------------------------------
- public boolean isServing(){
- return ServiceState;
- }
- //----------------------2、判断4个普通窗口是否同时都在为客户办理业务-------------------------
- public boolean isCommonsServing() {
- return COMMON1.isServing()&&COMMON2.isServing()&&COMMON3.isServing()&&COMMON4.isServing();
- }
- //-------------------3、办理业务的动作--------------------------------------------------
- public void serving(NumberManager numManager,int num,int randomTime){
- System.out.println(this+"窗口正在为"+numManager+"客户 "+num+"号 办理业务" );
- long startTime = System.currentTimeMillis();
- try{Thread.sleep((new Random().nextInt(randomTime)+1)*1000);}catch(Exception e){e.printStackTrace();}
- long usedTime = (System.currentTimeMillis()-startTime)/1000;
- System.out.println(this+"窗口已为"+numManager+"客户 "+num+"号 办理完业务,用时"+usedTime+"秒");
- ServiceState = false;//服务状态为假
- }
- //-------------------4、 为普通客户服务的方法 -------------------------------------------
- public void serveForCommon(){
- int num = 0;
- NumberManager numManager = null;
- synchronized(NumberManager.COMMON){
- numManager = NumberManager.COMMON;//获取普通号码管理器
- if(numManager.hasNumber()){ //--------------------------->必须同步的代码
- num = numManager.getNumber();//向号码管理器取号------->必须同步的代码
- ServiceState = true;//服务状态为正真
- }
- }
- if(ServiceState){
- serving(numManager, num, 10);//参数10指定服务时间为1~10秒
- }else {
- System.out.println(this+"窗口空闲中");
- try{Thread.sleep(1000);}catch(Exception e){e.printStackTrace();}//如果没人排除则休息1秒再去看有没有人排队
- }
- }
- //----------------------5、去问号码管理器取号,并为对应号码的客户办理业务-------------------
- public void getNumber() {
- long startTime = 0;
- long usedTime = 0; //如果窗口为4个普通窗口的任意一个,则他们取的号码都是普通号码
- if(name().equals("COMMON1")||name().equals("COMMON2")||name().equals("COMMON3")||name().equals("COMMON4")) {
- serveForCommon();
- }else if(name().equals("EXPRESS")){ //如果窗口是快速窗口
- NumberManager numManager = NumberManager.EXPRESS; //获取快速号码管理器
- if(numManager.hasNumber()){
- int num = numManager.getNumber();//取号
- serving(numManager, num, 1);//参数10指定服务时间为1秒
- }else { //如果没有快速客户
- if(isCommonsServing())//如果普通窗口都在忙,则帮忙处理普通客户
- serveForCommon();
- else {
- System.out.println(this+"窗口空闲中");
- try{Thread.sleep(1000);}catch(Exception e){e.printStackTrace();}//如果没人排除则休息1秒再去看有没有人排队
- }
- }
- }else{ //如果窗口是VIP窗口
- NumberManager numManager = NumberManager.VIP; //获取VIP号码管理器
- if(numManager.hasNumber()){
- int num = numManager.getNumber(); //取号
- serving(numManager, num, 10);//参数10指定服务时间为1~10秒
- }else { //如果没有VIP客户
- if(isCommonsServing())//如果普通窗口都在忙,则帮忙处理普通客户
- serveForCommon();
- else {
- System.out.println(this+"窗口空闲中");
- try{Thread.sleep(1000);}catch(Exception e){e.printStackTrace();}//如果没人排除则休息1秒再去看有没有人排队
- }
- }
- }
- }
- //---------------------重写toString---------------------------------------------------------
- public String toString(){
- if(name().equals("VIP"))
- return "VIP";
- else if(name().equals("EXPRESS"))
- return "快速";
- else if(name().equals("COMMON1"))
- return "普通1号";
- else if(name().equals("COMMON2"))
- return "普通2号";
- else if(name().equals("COMMON3"))
- return "普通3号";
- return "普通4号";
- }
- }
复制代码 第三个类:测试类- public class MainClass {
- public static void main(String[] args) {
- NumberManager num = NumberManager.COMMON;
- ServiceWindows window = ServiceWindows.COMMON1;
- }
- }
复制代码 |
|