设计思路:
(1)有三种对应类型的客户:VIP客户,普通客户,快速客户,异步随机生成各种类型的客户,各类型客户在其对应窗口按顺序依次办理业务。
(2)有三个类。NumberManager类,NumberMachine类,Serverwindow类(抽象类,有三个子类)
(一)NumberMachinery类
1.NumberManage对象总共有三个,由NumberMachinery控制,所以定义成三个成员变量。
2.NumberMachinery是唯一的,所以使用单例设计。
代码如下:
public class Numbermachinery {/**该类使用单例设计模式*使用饿汉式 */private Numbermachinery(){}private static final Numbermachinery numberMacInstance = new Numbermachinery();private static Numbermanager com = new Numbermanager();private static Numbermanager exp = new Numbermanager();private static Numbermanager vip = new Numbermanager(); public static Numbermachinery getInstance(){return numberMacInstance;}public Numbermanager commonNumber(){return com;}public Numbermanager expressNumber(){return exp;}public Numbermanager vipNumber(){return vip;} }
(二)NumberManager类
有两个方法:generateNumber()产生号码,fetchNunber()对外提供获取号码的方法。
1.因为要频繁的增删,所有使用LinkedList集合。
2.两个方法都涉及不同的线程,所以要实现同步。
3.对于获取null号码,为避免空指针,让它返回-1
代码如下:
import java.util.LinkedList; public class Numbermanager {/**两个方法。* 一个产生号码,一个提供外界对号码的访问 * */int num=0;
//存储号码的容器
LinkedList<Integer> link = new LinkedList<Integer>();
//产生号码的方法 public synchronized int numberGenerate() { link.offerLast(++num); return num; } //提供获取号码的方法 public synchronized Integer fetchNumber(){ Integer num = link.pollFirst(); if(num==null){ return -1; } else{ return num; } } }
(三)Numbertype 枚举类
1.将三种类型的客户用一个枚举类来表示,非常方便,其中定义的三个成员分别表示三种类型的客户。
2.覆盖toString方法,返回类型的中文名称。
代码如下:
package bankdemo;public enum Numbertype {COMMON,EXPRESS,VIP;public String toString(){if(this==Numbertype.COMMON){return "普通";}if(this==Numbertype.EXPRESS){return "快速";}elsereturn "VIP"; } }
(四)ServerWindow类。
因为三个类有共同的功能但是功能主体不同,所以抽取父类,让这三个类继承。考虑到现实中,普通窗口可以随时变成VIP窗口和快速窗口。也可以定义成一个类,三个方法。
1.三个类继承抽象类。
2.内被定义一个线程,让三个窗口实现轮流叫号。
3.抽象方法用于显示信息,和耗时的计算。
代码如下:
import java.util.Random; import java.util.concurrent.Executors; public abstract class Serverwindow {public Numbertype type= Numbertype.COMMON;public int windowId=1; public String windowName;public void setType(Numbertype type){ this.type=type;}public void setWindowId(int windowId){this.windowId=windowId; } public void windowServer() {Executors.newSingleThreadExecutor().execute(new Runnable(){ public void run(){//注意while循环的放置位置,要在一个线程run方法中。 while(true){ try {Thread.sleep(1000);} catch (InterruptedException e2) { e2.printStackTrace();} Integer num = getNum();windowName = windowId+ "号" + type + "窗口";try {Thread.sleep(1500);} catch (InterruptedException e1) { e1.printStackTrace();}if (num == -1) {print1(); helpWindow();} else { print2(num); long start = System.currentTimeMillis(); long serverTime = getServerTime();try { Thread.sleep(serverTime); } catch (InterruptedException e) {e.printStackTrace();}long end = System.currentTimeMillis();print3(num, end - start);}}} }); } public abstract void print1();//显示没有获取到任务的信息,public abstract void print2(int num);//显示开始服务的信息public abstract void print3(int num,long time);//显示服务的时间的信息public abstract void helpWindow();//快速窗口和VIP窗口对普通窗口服务public abstract long getServerTime();//服务时间public abstract int getNum();//获取号码 }class CommonServerWindow extends Serverwindow{ public void print1(){System.out.println( windowName+"没有获取到普通客户服务>>>>>");System.out.println(windowName + "休息1秒");try {Thread.sleep(1000);} catch (InterruptedException e) { e.printStackTrace();}} public void print2(int num){System.out.println( windowName+"获取到"+num+"号普通服务,开始服务");} public void print3(int num,long time){System.out.println( windowName+"为"+num+"号普通客户服务完毕,耗时"+time+"秒");} public void helpWindow(){ } public long getServerTime() { long serverTime =new Random().nextInt((ConstantDemo.MAX-ConstantDemo.MIN)/1000)+1;return serverTime*1000+ConstantDemo.MIN;} public int getNum() { return Numbermachinery.getInstance().commonNumber().fetchNumber();} } class ExpressServerWindow extends Serverwindow{ public void print1() { System.out.println(windowName+"没有获取到快速客户服务》》》"); System.out.println(windowName + "休息1秒");} public void print2(int num) { System.out.println(windowName+"获取到"+num+"号快速服务,开始服务");} public void print3(int num, long time) { System.out.println(windowName+"为"+num+"号.快速客户服务完毕,耗时"+time+"秒");}public void helpWindow() { //快速窗口为普通客户服务 CommonServerWindow cs=new CommonServerWindow();cs.setType(Numbertype.EXPRESS);cs.setWindowId(1);cs.windowServer(); } public long getServerTime() { return ConstantDemo.MIN;} public int getNum() { return Numbermachinery.getInstance().expressNumber().fetchNumber();} } class VIPServerWindow extends Serverwindow{ public void print1() {System.out.println(windowName+"没有获取到VIP客户服务"); System.out.println(windowName + "休息1秒");} public void print2(int num) {System.out.println(windowName+"获取到"+num+"号VIP服务,开始服务"); }public void print3(int num, long time) {System.out.println(windowName+"为"+num+"号..VIP客户服务完毕,耗时"+time+"秒"); } public void helpWindow() {//VIP窗口为普通客户服务 CommonServerWindow cs=new CommonServerWindow();cs.setType(Numbertype.VIP);cs.setWindowId(1);cs.windowServer(); } public long getServerTime() { return ConstantDemo.MAX;} public int getNum() {return Numbermachinery.getInstance().vipNumber().fetchNumber();}}
(五)常量的类
public class ConstantDemo { public static final int MAX=3000;public static final int MIN=1000; }
(六)mian方法。
1.使用for循环,产生四个普通窗口。而快速窗口和VIP窗口,设定为只有一个窗口。
2.使用Executors线程工具类,产生三个单独的线程,进行产生号码。
import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; public class MainDemo { public static void main(String[] args) {//设置4个普通窗口 for(int x=1;x<5;x++){ CommonServerWindow commonwindow = new CommonServerWindow();//new 4次 commonwindow.setWindowId(x);commonwindow.setType(Numbertype.COMMON); commonwindow.windowServer(); } Serverwindow expresswindow = new ExpressServerWindow();expresswindow.setType(Numbertype.EXPRESS);expresswindow.windowServer();VIPServerWindow vipwindow= new VIPServerWindow();vipwindow.setType(Numbertype.VIP);vipwindow.windowServer();Executors.newScheduledThreadPool(1).scheduleAtFixedRate(new Runnable(){ public void run() {Integer num = Numbermachinery.getInstance().commonNumber().numberGenerate();if(num!=null){ System.out.println("普通客户"+num+"号等待服务");} } } ,0, 1,TimeUnit.SECONDS);Executors.newScheduledThreadPool(1).scheduleAtFixedRate(new Runnable(){ public void run() {Integer num =Numbermachinery.getInstance().expressNumber().numberGenerate();;if(num!=null){ System.out.println("快速客户"+num+"号等待服务");} } } ,0, 4,TimeUnit.SECONDS);Executors.newScheduledThreadPool(1).scheduleAtFixedRate(new Runnable(){ public void run() {Integer num = Numbermachinery.getInstance().vipNumber().numberGenerate(); if(num!=null){ System.out.println("VIP客户"+num+"号等待服务");} } } ,0, 7,TimeUnit.SECONDS); } }