黑马程序员_银行调度业务系统

---------------------- <a href="http://edu.csdn.net"target="blank">ASP.Net+Android+IO开发S</a>、<a href="http://edu.csdn.net"target="blank">.Net培训</a>、期待与您交流! ----------------------

感觉比交通灯的复杂一些.

        这个系统主要分成3个部分来做,分别是,号码管理器,号码产生的机器和服务窗口三个部分.号码管理器( NumberManager)的主要做作用是产生新的号码和取号.里面涉及多线程的安全问题,因此要注意对共有资源语句的同步.号码产生的机器的主要作用是管理3个不同客户对象的号码,要保证它的唯一性,所以将它设计成单例模式.服务窗口(ServiceWindow)针对三个不同的串口进行服务,里面涉及的主要是取号及服务时间的问题.

       一.号码管理器( NumberManager)的设计

       有 2个方法,产生新号和取号的操作,以为这2个线程同时对号码的资源进行操作,为避免安全问题,将方法同步.代码如下:

import java.util.ArrayList;
import java.util.List;

public class NumberManager {  //负责对号码的操作
private List number = new ArrayList();  //存储已经办理的号码
private int LastNumber = 0;  
public synchronized Integer generateNumber(){  //产生新号的方法
number.add(++LastNumber);  //将所有号码添进集合,方便以后取出
return ++LastNumber;  //返回新的号码
}
public synchronized Integer fetchNumber(){ //取号方法
if (number.size()>0) {
return (Integer)number.remove(0);   //取到号
}else
return null;
}
}

      二.号码产生的机器   

      号码的产生是由三个不同的号码管理器产生的,因此将他们三个封装在一个对象里,为保证它的唯一性,将其单例化,代码如下:

public class NumberMachine {  //产生三个不同客户的对象
private NumberManager commonManage = new NumberManager();
private NumberManager rapidManage = new NumberManager();
private NumberManager VIP = new NumberManager();
public NumberManager getCommonManage() {
return commonManage;
}
public NumberManager getRapidManage() {
return rapidManage;
}
public NumberManager getVIP() {
return VIP;
}
//因为只可能有一个NumberMachine,所以将它设计成单例模式
private NumberMachine(){}
private static NumberMachine numberMachine = new NumberMachine();
public static  NumberMachine getInstance(){
return numberMachine;
}
}

      三.服务窗口的设计

      怕把自己又绕晕了,所以暂时没有对其优化.这是分别对这三类客户进行的服务,

      首先,客户类型是固定的,所以 将它设计为枚举类型,代码如下:

public enum ClientType {
COMMONCLIENT,REPIDCLIENT,VIP;
public String toString(){
switch(this){
case COMMONCLIENT:
return "普通";
case REPIDCLIENT:
return "快速";
case VIP:
return "VIP";
}
return null;
}
}

        里面涉及到的时间的常量也单独建立一个类,

public class Constant {
 public static int MAX_SERVE_TIME = 10000;
 public static int Min_SERVE_TIME = 1000;
 public static int COMMON_CUSTOMER_INTEVAL_TIME = 1;
}

       开始取号判断,分别对取号的情况进行处理,如取到号与没有取到号的情况.代码如下:

import java.util.Random;
import java.util.concurrent.Executors;


public class ServiceWindow {
private ClientType type = ClientType.COMMONCLIENT;  //客户类型
private int windowId = 1; //窗口号
public void setType(ClientType type) {
this.type = type;
}
public void setWindowId(int windowId) {
this.windowId = windowId;
}
public void start(){
Executors.newSingleThreadExecutor().execute(new Runnable(){


@Override
public void run() {
while(true){
switch(type){
case COMMONCLIENT:
commonServe();
break;
case REPIDCLIENT:
repidClient();
break;
case VIP:
VIPServe();
break;
}
}
}
private void VIPServe() {
String WindowName = "第"+windowId+"号"+type+"窗口";
System.out.println(WindowName+"正在获取服务");
Integer number = NumberMachine.getInstance().getVIP().fetchNumber();//取号
if (number!=null) {
long start = System.currentTimeMillis();
long end = System.currentTimeMillis();
long costTime = end - start;
int maxRandom = Constant.MAX_SERVE_TIME-Constant.Min_SERVE_TIME;
int serveTime = new Random().nextInt(maxRandom)+1+Constant.Min_SERVE_TIME;
try {
Thread.sleep(serveTime);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(WindowName+"为第"+number+"个"+"VIP客户服务:耗时"+costTime/1000);
}else{
System.out.println(WindowName+"获取服务失败,为普通客户服务");
commonServe();
}
}
private void repidClient() {
String WindowName = "第"+windowId+"号"+type+"窗口";
System.out.println(WindowName+"正在获取任务");
Integer number = NumberMachine.getInstance().getRapidManage().fetchNumber();
if (number!=null) {
long start = System.currentTimeMillis();
long end = System.currentTimeMillis();
try {
Thread.sleep(Constant.Min_SERVE_TIME);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
long costTime = end - start;
System.out.println(WindowName+"为第"+number+"个"+"快速客户服务:耗时"+costTime/1000);
}else{
System.out.println(WindowName+"没有获取到任务,为普通客户服务");
commonServe();
}
}
private void commonServe() {
String WindowName = "第"+windowId+"号"+type+"窗口";
System.out.println(WindowName+"正在获取任务");
Integer number = NumberMachine.getInstance().getCommonManage().fetchNumber();
if (number!=null) {
long start = System.currentTimeMillis();
int maxRandom = Constant.MAX_SERVE_TIME-Constant.Min_SERVE_TIME; 

int serveTime = new Random().nextInt(maxRandom)+1+Constant.Min_SERVE_TIME;
try {
Thread.sleep(serveTime);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
long end = System.currentTimeMillis();
long costTime = end-start;
System.out.println(WindowName+"为第"+number+"个"+"普通客户服务:耗           时"+costTime/1000);
}else{
System.out.println(WindowName+"没有取到任务,先休息一秒钟");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
});
}
}

        最后是对它进行测试,这是三个线程同时取号,因此开了3条线程,都在线程池里完成,注意处理给定的一些条件,如6个窗口,其中4个是普通客户窗口,一个快速窗口可一个VIP窗口,

VIP客户 :普通客户 :快速客户  =  1 3等,具体代码如下:

import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.logging.Logger;


public class Test {
private static Logger logger = Logger.getLogger("edu.csdn.bankqueue");
public static void main(String[] args) {
for (int i = 0; i < 5; i++) {  //四个普通窗口
ServiceWindow commonWindow = new ServiceWindow();
commonWindow.setWindowId(i);
commonWindow.start();
}
ServiceWindow repidWindow = new ServiceWindow(); //一个快速窗口
repidWindow.setType(ClientType.REPIDCLIENT);
repidWindow.start();

ServiceWindow VIP = new ServiceWindow(); //一个VIP窗口
VIP.setType(ClientType.VIP);
VIP.start();

Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
new Runnable(){
@Override
public void run() {
Integer number = NumberMachine.getInstance().getCommonManage().generateNumber();
System.out.println(number+"普通客户正在等待服务");
}
}, 
0, 
Constant.COMMON_CUSTOMER_INTEVAL_TIME, 
TimeUnit.SECONDS);
Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
new Runnable(){


@Override
public void run() {
Integer number = NumberMachine.getInstance().getRapidManage().generateNumber();
System.out.println(number+"快速客户正在等待服务");
}
}, 
0, 
Constant.COMMON_CUSTOMER_INTEVAL_TIME*3, //为什么是*2
TimeUnit.SECONDS);
Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
new Runnable(){


@Override
public void run() {
Integer number = NumberMachine.getInstance().getVIP().generateNumber();
System.out.println(number+"VIP客户正在等待服务");
}
}, 
0, 
Constant.COMMON_CUSTOMER_INTEVAL_TIME*6, 
TimeUnit.SECONDS);
}
}

         这个程序对我来说还是比较复杂的,经过反复的调试,其中错误很多,不仅需要思路,更需要细心跟耐心,

---------------------- <a href="http://edu.csdn.net"target="blank">ASP.Net+Android+IO开发S</a>、<a href="http://edu.csdn.net"target="blank">.Net培训</a>、期待与您交流! ----------------------


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值