银行业务调度系统

银行业务调度系统

调度线程池(按固定频率执行指定代码)

 

面向对象分析:

         三个类型的客户:VIP客户,普通客户,快速客户

 

号码管理器

有三个号码管理器,由一个号码机器管理

         两个成员变量int 类型lastNumber即最后服务的号码

         集合类型,queueNumber  服务队列

         两个方法:

                   因为下面两个方法是两个线程操作同一资源,所以加synchronized 上锁

1,  generateNumber();客户获得服务号码,开始排队

2,  fetchNumber();服务窗口叫号给对应客户办理业务

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

public class NumberManager {

	// 代码管理器,出号码
	private int lastNumber = 1;
	// 定义一个集合,模拟排队取号
	private List<Integer> queueNumber = new ArrayList<Integer>();

	// 获得号码,将号码存入集合中,开始排队
	public synchronized Integer generateNewManager() {
		queueNumber.add(lastNumber);
		return lastNumber++;
	}

	// 服务窗口叫号服务
	// 返回值封装成包装类,防止空指针异常
	public synchronized Integer fetchServiceNumber() {
		if (queueNumber.size() > 0) {
			return queueNumber.remove(0);
		}
		return null;
	}
}


号码机器:(需要设计成单例)

         getCommonManager();获取普通号码管理器

         getVipManager();获取VIP号码管理器

         getExpressManager();获取快速号码管理器

         getInstance();获取号码机器实例,因为只有一个机器,使用单立设计模式

//号码机器,管理三个号码管理器
public class NumberMachine {

	private static NumberMachine nm = new NumberMachine();
	// 三个成员,分别为普通号码,vip号码,快速号码
	private NumberManager commonManager = new NumberManager();
	private NumberManager vipManager = new NumberManager();
	private NumberManager expressManager = new NumberManager();

	// 单例,构造方法私有
	private NumberMachine() {
	}

	public static NumberMachine getInstance() {
		return nm;
	}

	// 获取普通取号器实例
	public NumberManager getCommonManager() {
		return commonManager;
	}

	// 获取vip取号器实例
	public NumberManager getVipManager() {
		return vipManager;
	}

	// 获取快速取号器实例
	public NumberManager getExpressManager() {
		return expressManager;
	}

}


服务窗口:

         ServiceWindow

                   Start();开始服务

下面三个方法分别代表三类服务

                   commonService();普通服务

                   expressService();快速服务

                   vipService();vip服务

 

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

//服务窗口
public class ServiceWindow {

	// 窗口类型,默认为普通窗口
	private Customer type = Customer.COMMON;
	// 窗口号,如:普通窗口就有4个,分别为1,2,3,4。默认为1
	private int windowId = 1;

	// 窗口开始办理业务
	public void start() {

		// jdk1.5特性,创建线程,从线程池里面直接取
		Executors.newSingleThreadExecutor().execute(new Runnable() {
			public void run() {
				while (true) {
					switch (type) {
					case COMMON:
						commonService();
						break;
					case EXPRESS:
						expressService();
						break;
					case VIP:
						vipService();
						break;
					}
				}
			}
		});
	}

	// 普通服务
	public void commonService() {
		// 通过号码机器获得普通号码管理器,并叫号
		System.out.println(windowId + "号" + type + "窗口正在等待服务");
		Integer number = NumberMachine.getInstance().getCommonManager()
				.fetchServiceNumber();
		if (number != null) {
			System.out.println(windowId + "号" + type + "窗口开始给" + number + "号普通客户服务");
			long startTime = System.currentTimeMillis();
			// 最大随机值应该是10000到1000之间
			int maxServiceTime = Constants.MAX_SERVICE_TIME
					- Constants.MIN_SERVICE_TIME;
			// 获取服务时间,线程sleep(),模拟服务
			long serverTime = new Random().nextInt(maxServiceTime) + 1
					+ Constants.MIN_SERVICE_TIME;
			try {
				Thread.sleep(serverTime);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			long costTime = System.currentTimeMillis() - startTime;
			// 取到要服务的号码,开始服务
			System.out.println(windowId + "号" + type + "窗口给" + number
					+ "号普通客户服务完,耗时" + costTime / 1000 + "秒");
		} else {
			// 窗口没取到号,休息1秒
			System.out.println(windowId + "窗口没有普通服务,休息一秒");
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}

	// vip服务
	public void vipService() {
		// 通过号码机器获得普通号码管理器,并叫号
		System.out.println(windowId + "号" + type + "窗口正在等待服务");
		Integer number = NumberMachine.getInstance().getVipManager()
				.fetchServiceNumber();
		if (number != null) {
			System.out.println(windowId + "号" + type + "窗口开始给" + number + "号vip客户服务");
			long startTime = System.currentTimeMillis();
			// 最大随机值应该是10000到1000之间
			int maxServiceTime = Constants.MAX_SERVICE_TIME
					- Constants.MIN_SERVICE_TIME;
			// 获取服务时间,线程sleep(),模拟服务
			long serverTime = new Random().nextInt(maxServiceTime) + 1
					+ Constants.MIN_SERVICE_TIME;
			try {
				Thread.sleep(serverTime);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			long costTime = System.currentTimeMillis() - startTime;
			// 取到要服务的号码,开始服务
			System.out.println(windowId + "号" + type + "窗口给" + number
					+ "号vip客户服务完,耗时" + costTime / 1000 + "秒");
		} else {
			// 窗口没取到号,继续普通服务
			System.out.println(windowId + "窗口没有vip服务,开始取普通服务");
			commonService();
		}
	}

	// 快速服务
	public void expressService() {
		// 通过号码机器获得普通号码管理器,并叫号
		System.out.println(windowId + "号" + type + "窗口正在等待服务");
		Integer number = NumberMachine.getInstance().getExpressManager()
				.fetchServiceNumber();
		if (number != null) {
			System.out.println(windowId + "号" + type + "窗口开始给" + number + "号快速客户服务");
			long startTime = System.currentTimeMillis();
			// 获取服务时间,线程sleep(),模拟服务
			// 快速服务时间为最小服务时间
			long serverTime = Constants.MIN_SERVICE_TIME;
			try {
				Thread.sleep(serverTime);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			long costTime = System.currentTimeMillis() - startTime;
			// 取到要服务的号码,开始服务
			System.out.println(windowId + "号" + type + "窗口给" + number
					+ "号快速客户服务完,耗时" + costTime / 1000 + "秒");
		} else {
			// 窗口没取到号,继续普通服务
			System.out.println(windowId + "窗口没有快速服务,开始取普通服务");
			commonService();
		}
	}

	// 银行窗口可能改变,如普通窗口可以换成VIP窗口
	public void setType(Customer type) {
		this.type = type;
	}

	// 窗口号也可设置,如1,2号窗口可以互换编号
	public void setWindowId(int windowId) {
		this.windowId = windowId;
	}

}

场景类:

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

public class MainClass {

	public static void main(String[] args) {
		// 先创建4个普通窗口
		for (int i = 1; i < 5; i++) {
			ServiceWindow comWindow = new ServiceWindow();
			comWindow.setWindowId(i);
			comWindow.start();
		}
		// 创建vip窗口
		ServiceWindow vipWindow = new ServiceWindow();
		vipWindow.setType(Customer.VIP);
		vipWindow.setWindowId(5);
		vipWindow.start();
		// 创建快速窗口
		ServiceWindow expressWindow = new ServiceWindow();
		expressWindow.setType(Customer.EXPRESS);
		expressWindow.setWindowId(6);
		expressWindow.start();

		// 创建线程,模拟来的客户,使用线程调度池,不停的执行指定代码
		// 模拟普通客户
		Executors.newScheduledThreadPool(1).scheduleAtFixedRate(new Runnable() {
			public void run() {

				Integer number = NumberMachine.getInstance().getCommonManager()
						.generateNewManager();
				System.out.println("第" + number + "号普通客户来了,等待服务");
			}
		}, 0, Constants.COMMON_CUSTOMER_INTERVAL_TIME, TimeUnit.SECONDS);
		// 模拟vip客户
		Executors.newScheduledThreadPool(1).scheduleAtFixedRate(new Runnable() {

			public void run() {
				Integer number = NumberMachine.getInstance().getVipManager()
						.generateNewManager();
				System.out.println("第" + number + "号vip客户来了,等待服务");
			}
		}, 0, Constants.COMMON_CUSTOMER_INTERVAL_TIME * 6, TimeUnit.SECONDS);
		// 模拟快速客户
		Executors.newScheduledThreadPool(1).scheduleAtFixedRate(new Runnable() {

			public void run() {
				Integer number = NumberMachine.getInstance()
						.getExpressManager().generateNewManager();
				System.out.println("第" + number + "号快速客户来了,等待服务");
			}
		}, 0, Constants.COMMON_CUSTOMER_INTERVAL_TIME * 2, TimeUnit.SECONDS);
	}
}

常量类:

public class Constants {

	// 最大服务时间
	public static int MAX_SERVICE_TIME = 10000;
	// 最小服务时间
	public static int MIN_SERVICE_TIME = 1000;
//	普通客户来的时间
	public static int COMMON_CUSTOMER_INTERVAL_TIME = 1;
}
客户类(枚举):

public enum Customer {

	VIP, COMMON, EXPRESS;

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



代码优化:

可以将vip窗口,和快速窗口设计成普通窗口的子类,

只需从写普通服务commonService()方法中的部分代码即可

提高代码复用性


运行结果:

1号普通窗口正在等待服务
1窗口没有普通服务,休息一秒
4号普通窗口正在等待服务
4窗口没有普通服务,休息一秒
5号VIP窗口正在等待服务
5窗口没有vip服务,开始取普通服务
5号VIP窗口正在等待服务
5窗口没有普通服务,休息一秒
2号普通窗口正在等待服务
2窗口没有普通服务,休息一秒
3号普通窗口正在等待服务
3窗口没有普通服务,休息一秒
第1号vip客户来了,等待服务
第1号快速客户来了,等待服务
6号快速窗口正在等待服务
6号快速窗口开始给1号快速客户服务
第1号普通客户来了,等待服务
5号VIP窗口正在等待服务
1号普通窗口正在等待服务
1号普通窗口开始给1号普通客户服务
4号普通窗口正在等待服务
4窗口没有普通服务,休息一秒
5号VIP窗口开始给1号vip客户服务
第2号普通客户来了,等待服务
2号普通窗口正在等待服务
3号普通窗口正在等待服务
3号普通窗口开始给2号普通客户服务
2窗口没有普通服务,休息一秒
6号快速窗口给1号快速客户服务完,耗时1秒
6号快速窗口正在等待服务
6窗口没有快速服务,开始取普通服务
6号快速窗口正在等待服务
6窗口没有普通服务,休息一秒
4号普通窗口正在等待服务
4窗口没有普通服务,休息一秒
第3号普通客户来了,等待服务
2号普通窗口正在等待服务
2号普通窗口开始给3号普通客户服务
第2号快速客户来了,等待服务
6号快速窗口正在等待服务
6号快速窗口开始给2号快速客户服务
3号普通窗口给2号普通客户服务完,耗时1秒
3号普通窗口正在等待服务
3窗口没有普通服务,休息一秒
4号普通窗口正在等待服务
4窗口没有普通服务,休息一秒
第4号普通客户来了,等待服务
6号快速窗口给2号快速客户服务完,耗时1秒
6号快速窗口正在等待服务
6窗口没有快速服务,开始取普通服务
6号快速窗口正在等待服务
6号快速窗口开始给4号普通客户服务
5号VIP窗口给1号vip客户服务完,耗时2秒
5号VIP窗口正在等待服务
5窗口没有vip服务,开始取普通服务
5号VIP窗口正在等待服务
5窗口没有普通服务,休息一秒
3号普通窗口正在等待服务
3窗口没有普通服务,休息一秒
4号普通窗口正在等待服务
4窗口没有普通服务,休息一秒
第5号普通客户来了,等待服务
第3号快速客户来了,等待服务
5号VIP窗口正在等待服务
5窗口没有vip服务,开始取普通服务
5号VIP窗口正在等待服务
5号VIP窗口开始给5号普通客户服务
3号普通窗口正在等待服务
3窗口没有普通服务,休息一秒
1号普通窗口给1号普通客户服务完,耗时3秒
1号普通窗口正在等待服务
1窗口没有普通服务,休息一秒
4号普通窗口正在等待服务
4窗口没有普通服务,休息一秒
第6号普通客户来了,等待服务
3号普通窗口正在等待服务
3号普通窗口开始给6号普通客户服务
1号普通窗口正在等待服务
1窗口没有普通服务,休息一秒
4号普通窗口正在等待服务
4窗口没有普通服务,休息一秒
第7号普通客户来了,等待服务
第4号快速客户来了,等待服务
第2号vip客户来了,等待服务
1号普通窗口正在等待服务
1号普通窗口开始给7号普通客户服务
3号普通窗口给6号普通客户服务完,耗时1秒
3号普通窗口正在等待服务
3窗口没有普通服务,休息一秒
4号普通窗口正在等待服务
4窗口没有普通服务,休息一秒
第8号普通客户来了,等待服务
3号普通窗口正在等待服务
3号普通窗口开始给8号普通客户服务
4号普通窗口正在等待服务
4窗口没有普通服务,休息一秒
第9号普通客户来了,等待服务
第5号快速客户来了,等待服务
5号VIP窗口给5号普通客户服务完,耗时4秒
5号VIP窗口正在等待服务
5号VIP窗口开始给2号vip客户服务
4号普通窗口正在等待服务
4号普通窗口开始给9号普通客户服务
第10号普通客户来了,等待服务

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值