银行业务调度系统的实现

来源:互联网 发布:python编程入门下载 编辑:程序博客网 时间:2024/06/12 23:05
需求:
银行业务调度系统


模拟实现银行业务调度系统逻辑,具体需求如下:
 银行内有6个业务窗口,1 - 4号窗口为普通窗口,5号窗口为快速窗口,6号窗口为VIP窗口。
 有三种对应类型的客户:VIP客户,普通客户,快速客户(办理如交水电费、电话费之类业务的客户)。
 异步随机生成各种类型的客户,生成各类型用户的概率比例为:
        VIP客户 :普通客户 :快速客户  =  1 :6 :3。
 客户办理业务所需时间有最大值和最小值,在该范围内随机设定每个VIP客户以及普通客户办理业务所需的时间,快速客户办理业务所需时间为最小值(提示:办理业务的过程可通过线程Sleep的方式模拟)。
 各类型客户在其对应窗口按顺序依次办理业务。 
 当VIP(6号)窗口和快速业务(5号)窗口没有客户等待办理业务的时候,这两个窗口可以处理普通客户的业务,而一旦有对应的客户等待办理业务的时候,则优先处理对应客户的业务。
 随机生成客户时间间隔以及业务办理时间最大值和最小值自定,可以设置。
 不要求实现GUI,只考虑系统逻辑实现,可通过Log方式展现程序运行结果。


补充:
   银行可能会出现vip的窗口正在办理一个vip用户的业务,而普通窗口此时空闲,那么再来一个vip用户(不管是什么用户),他应该是可以去普通窗口办理业务的#

   我的核心处理逻辑就是,有一个WindowList,它里面持有者所有的Winodw(就是银行的服务窗口),它有getIdelVIPWindow,getIdelNormalWindow等方法,顾名思义,getIdelVIPWindow就是获取现在空闲的一个VIP窗口#(Window里面有一个字段是isBusy,是boolean型的)

   有一个Produce,它负责按照1:6:3的比例产生各种客户,分别放到normals,vips,quicks等3个队列

   Consumer就是一个个客户,它有execute方法#顾客去柜台办理业务的时候,所花的时间和柜台没有关系,只和自己的业务相关#因此,execute里面会根据consumer的type来决定线程sleep多长时间

   调度器就是dispatcher,它调用Produce不断生成客户,通过WindowList获得一个空闲的窗口,让这个窗口去"叫"自己对应的顾客#例如一个空闲的vip窗口,就会先去vip队列里找人,如果vip队列里面没有人,窗口就会去quick队列找人....

   类图如下:


   代码如下:


 
 package bank;/**    * This class is used for ...    * @author  dlf(460795365@qq.com) * @version 1.0, 2017年2月21日 下午10:10:46    */public class Consumer {public Integer id;public String type;public Consumer(Integer id,String type){this.id=id;this.type=type;}public void execute(){try{if (type.equals("normal")) {Thread.sleep(1000);return ;}if (type.equals("quick")) {Thread.sleep(300);return ;}if (type.equals("vip")) {Thread.sleep(1000);return ;}}catch(Exception exception){exception.printStackTrace();}}}

package bank;/** * This class is used for ... *  * @author dlf(460795365@qq.com) * @version 1.0, 2017年2月21日 下午6:50:55 */public abstract class Window {public int id;public String type;public Boolean isBusy;public void execute(Consumer client) {System.out.println(id + "号" + type + "业务员 开始办理" + client.id + "号" + client.type + "顾客的业务");isBusy = true;client.execute();isBusy = false;System.out.println(id + "号normal业务员 办理完了" + client.id + "号" + client.type + "顾客的业务");}}class WindowForVIP extends Window {public WindowForVIP(int i) {id = i;type = "vip";isBusy = false;}}class WindowForNormal extends Window {public WindowForNormal(int i) {id = i;type = "normal";isBusy = false;}}class WindowForQuick extends Window {public WindowForQuick(int i) {id = i;type = "quick";isBusy = false;}}


package bank;import java.util.ArrayList;import java.util.List;/**    * This class is used for ...    * @author  dlf(460795365@qq.com) * @version 1.0, 2017年2月21日 下午7:55:34    */public class WindowList {public List<WindowForNormal> normallist=new ArrayList<>();public List<WindowForVIP> viplist=new ArrayList<>();public List<WindowForQuick> quicklist=new ArrayList<>();public WindowList(){for(int i=1;i<5;i++)normallist.add(new WindowForNormal(i));quicklist.add(new WindowForQuick(5));viplist.add(new WindowForVIP(6));}public Window getIdelVIPWindow(){for(Window s:viplist){if(!s.isBusy){return s;}}return null;}public Window getIdelNormalWindow(){for(Window s:normallist){if(!s.isBusy){return s;}}return null;}public Window getIdelQuickWindow(){for(Window s:quicklist){if(!s.isBusy){return s;}}return null;}}


package bank;import java.util.Random;import java.util.concurrent.ArrayBlockingQueue;/**    * This class is used for ...    * @author  dlf(460795365@qq.com) * @version 1.0, 2017年2月21日 下午7:01:18    */public class Producer {//省略get/set方法public ArrayBlockingQueue<Consumer> normals;public ArrayBlockingQueue<Consumer> vips;public ArrayBlockingQueue<Consumer> quicks;public void produce(){Random random=new Random();Random time=new Random();int i=1;try {while (true) {//产生1-10int type=random.nextInt(10)+1; if (type==1) {System.out.println("产生第"+i+"个客户,他是vip用户");vips.put(new Consumer(i++, "vip"));}else if (type<5) {System.out.println("产生第"+i+"个客户,他是快速用户");quicks.put(new Consumer(i++, "快速"));}else {System.out.println("产生第"+i+"个客户,他是普通用户");normals.put(new Consumer(i++, "普通"));}Thread.sleep(time.nextInt(1000));}} catch (Exception e) {// TODO: handle exception}}}



下面就是最核心的分发器,就是指派某个窗口处理某个顾客的逻辑

package bank;import java.util.concurrent.ArrayBlockingQueue;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.ThreadPoolExecutor;import java.util.concurrent.TimeUnit;/** * This class is used for ... *  * @author dlf(460795365@qq.com) * @version 1.0, 2017年2月21日 下午7:14:18 */public class Dispatcher {/** * @param threadPool * @param Windows * @param vips * @param normals * @param quicks */public void doQuick(ExecutorService threadPool, WindowList Windows, ArrayBlockingQueue<Consumer> vips,ArrayBlockingQueue<Consumer> normals, ArrayBlockingQueue<Consumer> quicks) {try {while (true) {// do vipfinal Window window = Windows.getIdelQuickWindow();if (window != null) {int flag = 0;final Consumer id_quick = quicks.poll(10, TimeUnit.MILLISECONDS);if (id_quick != null)// quick里面有人run(window, id_quick, threadPool);flag = 1;if (flag == 0) {final Consumer id_vip = vips.poll(10, TimeUnit.MILLISECONDS);if (id_vip != null)// quick里面没人 vip队伍里有人排队run(window, id_vip, threadPool);flag = 1;}if (flag == 0) {final Consumer id_normal = normals.poll(10, TimeUnit.MILLISECONDS);if (id_normal != null) {// quick也没有人 vip队伍里没人排队 normal 里面有人run(window, id_normal, threadPool);}}} else {// vip窗口正在忙Thread.sleep(1000);}}} catch (Exception e) {e.printStackTrace();}}/** * @param id_quick * @param threadPool */private static void run(final Window window, final Consumer consumer, ExecutorService threadPool) {threadPool.execute(new Runnable() {public void run() {window.execute(consumer);}});}/** * @param threadPool * @param list * @param vips */public void doNomal(ExecutorService threadPool, WindowList list, ArrayBlockingQueue<Consumer> vips,ArrayBlockingQueue<Consumer> normals, ArrayBlockingQueue<Consumer> quicks) {try {while (true) {// do vipfinal Window window = list.getIdelNormalWindow();if (window != null) {int flag = 0;final Consumer id_normal = normals.poll(10, TimeUnit.MILLISECONDS);if (id_normal != null)// normal 里面有人run(window, id_normal, threadPool);flag = 1;if (flag == 0) {final Consumer id_quick = quicks.poll(10, TimeUnit.MILLISECONDS);if (id_quick != null)// normal里面没人 quick里面有人run(window, id_quick, threadPool);flag = 1;}if (flag == 0) {final Consumer id_vip = vips.poll(10, TimeUnit.MILLISECONDS);if (id_vip != null)// normal里面没人 normal里面没人 vip队伍里有人排队run(window, id_vip, threadPool);flag = 1;}} else {// normal窗口正在忙Thread.sleep(1000);}}} catch (Exception e) {e.printStackTrace();}}/** * @param vips * @param list * @param threadPool * @param quicks * @param normals *  */public void doVIP(ExecutorService threadPool, WindowList list, ArrayBlockingQueue<Consumer> vips,ArrayBlockingQueue<Consumer> normals, ArrayBlockingQueue<Consumer> quicks) {try {while (true) {// do vipfinal Window window = list.getIdelVIPWindow();if (window != null) {// vip窗口空闲// System.out.println("vips is null? "+vips==null);final Consumer id_vip = vips.poll(10, TimeUnit.MILLISECONDS);int flag = 0;if (id_vip != null) {// vip队伍里有人排队run(window, id_vip, threadPool);flag = 1;}if (flag == 0) {final Consumer id_quick = quicks.poll(10, TimeUnit.MILLISECONDS);if (id_quick != null)// vip队伍里没人排队 quick里面有人run(window, id_quick, threadPool);flag = 1;}if (flag == 0) {final Consumer id_normal = normals.poll(10, TimeUnit.MILLISECONDS);if (id_normal != null)// vip队伍里没人排队 quick也里面有人 normal 里面有人run(window, id_normal, threadPool);}} else {// vip窗口正在忙Thread.sleep(1000);}}} catch (Exception e) {e.printStackTrace();}}}


OK,我们看看测试代码

package bank;import java.util.concurrent.ArrayBlockingQueue;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.ThreadPoolExecutor;/**    * This class is used for ...    * @author  dlf(460795365@qq.com) * @version 1.0, 2017年2月22日 下午5:22:01    */public class Main {public static void main(String[] args) {final ExecutorService threadPool = Executors.newCachedThreadPool();// 每个队伍 最多有10人final ArrayBlockingQueue<Consumer> normals = new ArrayBlockingQueue<>(10);final ArrayBlockingQueue<Consumer> vips = new ArrayBlockingQueue<>(10);final ArrayBlockingQueue<Consumer> quicks = new ArrayBlockingQueue<>(10);final WindowList Windows = new WindowList();final Dispatcher dispatcher=new Dispatcher();final Producer producer = new Producer();producer.setNormals(normals);producer.setQuicks(quicks);producer.setVips(vips);threadPool.execute(new Runnable() {public void run() {producer.produce();}});threadPool.execute(new Runnable() {public void run() {dispatcher.doVIP(threadPool, Windows, vips, normals, quicks);}});threadPool.execute(new Runnable() {public void run() {dispatcher.doQuick(threadPool, Windows, vips, normals, quicks);}});threadPool.execute(new Runnable() {public void run() {dispatcher.doNomal(threadPool, Windows, vips, normals, quicks);}});threadPool.execute(new Runnable() {public void run() {try {while (true) {// http://blog.csdn.net/yingzishizhe/article/details/8769907int threadCount = ((ThreadPoolExecutor) threadPool).getActiveCount();System.out.println("现在活跃的线程数量为: " + threadCount);System.out.println("现在排队的人数为:" + (vips.size() + normals.size() + quicks.size()));Thread.sleep(3000);}} catch (Exception e) {e.printStackTrace();}}});}}最后的打印出来的信息如下:
产生第1个客户,他是快速用户现在活跃的线程数量为: 5现在排队的人数为:05号quick业务员 开始办理1号快速顾客的业务5号normal业务员 办理完了1号快速顾客的业务产生第2个客户,他是普通用户1号normal业务员 开始办理2号普通顾客的业务1号normal业务员 办理完了2号普通顾客的业务产生第3个客户,他是快速用户5号quick业务员 开始办理3号快速顾客的业务5号normal业务员 办理完了3号快速顾客的业务产生第4个客户,他是普通用户1号normal业务员 开始办理4号普通顾客的业务1号normal业务员 办理完了4号普通顾客的业务产生第5个客户,他是快速用户5号quick业务员 开始办理5号快速顾客的业务5号normal业务员 办理完了5号快速顾客的业务现在活跃的线程数量为: 5现在排队的人数为:0产生第6个客户,他是普通用户1号normal业务员 开始办理6号普通顾客的业务1号normal业务员 办理完了6号普通顾客的业务产生第7个客户,他是快速用户5号quick业务员 开始办理7号快速顾客的业务5号normal业务员 办理完了7号快速顾客的业务产生第8个客户,他是快速用户5号quick业务员 开始办理8号快速顾客的业务5号normal业务员 办理完了8号快速顾客的业务产生第9个客户,他是普通用户1号normal业务员 开始办理9号普通顾客的业务1号normal业务员 办理完了9号普通顾客的业务产生第10个客户,他是快速用户5号quick业务员 开始办理10号快速顾客的业务5号normal业务员 办理完了10号快速顾客的业务产生第11个客户,他是普通用户1号normal业务员 开始办理11号普通顾客的业务1号normal业务员 办理完了11号普通顾客的业务现在活跃的线程数量为: 5现在排队的人数为:0产生第12个客户,他是普通用户1号normal业务员 开始办理12号普通顾客的业务1号normal业务员 办理完了12号普通顾客的业务产生第13个客户,他是快速用户5号quick业务员 开始办理13号快速顾客的业务5号normal业务员 办理完了13号快速顾客的业务产生第14个客户,他是普通用户1号normal业务员 开始办理14号普通顾客的业务1号normal业务员 办理完了14号普通顾客的业务产生第15个客户,他是普通用户1号normal业务员 开始办理15号普通顾客的业务1号normal业务员 办理完了15号普通顾客的业务产生第16个客户,他是普通用户1号normal业务员 开始办理16号普通顾客的业务1号normal业务员 办理完了16号普通顾客的业务现在活跃的线程数量为: 5现在排队的人数为:0产生第17个客户,他是快速用户5号quick业务员 开始办理17号快速顾客的业务5号normal业务员 办理完了17号快速顾客的业务产生第18个客户,他是普通用户1号normal业务员 开始办理18号普通顾客的业务1号normal业务员 办理完了18号普通顾客的业务产生第19个客户,他是普通用户1号normal业务员 开始办理19号普通顾客的业务1号normal业务员 办理完了19号普通顾客的业务产生第20个客户,他是普通用户1号normal业务员 开始办理20号普通顾客的业务1号normal业务员 办理完了20号普通顾客的业务产生第21个客户,他是快速用户5号quick业务员 开始办理21号快速顾客的业务5号normal业务员 办理完了21号快速顾客的业务产生第22个客户,他是普通用户1号normal业务员 开始办理22号普通顾客的业务1号normal业务员 办理完了22号普通顾客的业务现在活跃的线程数量为: 5现在排队的人数为:0产生第23个客户,他是普通用户1号normal业务员 开始办理23号普通顾客的业务1号normal业务员 办理完了23号普通顾客的业务产生第24个客户,他是普通用户1号normal业务员 开始办理24号普通顾客的业务1号normal业务员 办理完了24号普通顾客的业务产生第25个客户,他是普通用户1号normal业务员 开始办理25号普通顾客的业务1号normal业务员 办理完了25号普通顾客的业务产生第26个客户,他是普通用户1号normal业务员 开始办理26号普通顾客的业务1号normal业务员 办理完了26号普通顾客的业务产生第27个客户,他是快速用户6号vip业务员 开始办理27号快速顾客的业务6号normal业务员 办理完了27号快速顾客的业务产生第28个客户,他是普通用户1号normal业务员 开始办理28号普通顾客的业务1号normal业务员 办理完了28号普通顾客的业务现在活跃的线程数量为: 5现在排队的人数为:0产生第29个客户,他是普通用户1号normal业务员 开始办理29号普通顾客的业务1号normal业务员 办理完了29号普通顾客的业务产生第30个客户,他是普通用户1号normal业务员 开始办理30号普通顾客的业务1号normal业务员 办理完了30号普通顾客的业务产生第31个客户,他是普通用户1号normal业务员 开始办理31号普通顾客的业务1号normal业务员 办理完了31号普通顾客的业务产生第32个客户,他是快速用户5号quick业务员 开始办理32号快速顾客的业务5号normal业务员 办理完了32号快速顾客的业务产生第33个客户,他是普通用户1号normal业务员 开始办理33号普通顾客的业务1号normal业务员 办理完了33号普通顾客的业务现在活跃的线程数量为: 5现在排队的人数为:0产生第34个客户,他是快速用户6号vip业务员 开始办理34号快速顾客的业务6号normal业务员 办理完了34号快速顾客的业务产生第35个客户,他是普通用户1号normal业务员 开始办理35号普通顾客的业务1号normal业务员 办理完了35号普通顾客的业务产生第36个客户,他是普通用户1号normal业务员 开始办理36号普通顾客的业务1号normal业务员 办理完了36号普通顾客的业务产生第37个客户,他是普通用户1号normal业务员 开始办理37号普通顾客的业务1号normal业务员 办理完了37号普通顾客的业务现在活跃的线程数量为: 5现在排队的人数为:0产生第38个客户,他是普通用户1号normal业务员 开始办理38号普通顾客的业务1号normal业务员 办理完了38号普通顾客的业务产生第39个客户,他是快速用户5号quick业务员 开始办理39号快速顾客的业务5号normal业务员 办理完了39号快速顾客的业务产生第40个客户,他是vip用户6号vip业务员 开始办理40号vip顾客的业务产生第41个客户,他是普通用户1号normal业务员 开始办理41号普通顾客的业务1号normal业务员 办理完了41号普通顾客的业务6号normal业务员 办理完了40号vip顾客的业务现在活跃的线程数量为: 5现在排队的人数为:0




3 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 qq红包输了钱怎么办 qq红包实名认证没有银行卡怎么办 扣扣红包发不了怎么办 qb充错账号了怎么办 q币冲错了号了怎么办 微信qb冲错号码怎么办 微信qb冲错了怎么办 qb冲到小号了怎么办 无意中充了q币怎么办 在绝地求生里打不开充值页面怎么办 电脑版迷你世界打不开怎么办 电脑的腾讯视频打不开怎么办 好多程序连不上网了怎么办 掌游宝炉石传说卡组复制不了怎么办 花呗不能充话费怎么办 想用话费充王者怎么办 苹果6s激活出错怎么办 联通话费充多了怎么办? 电信宽带充值充到别人账号了怎么办 未实名的支付宝钱转不出来怎么办 手机打游戏闪屏怎么办 支付宝手机冲错怎么办 手机停用了支付宝充值码怎么办 苹果手机桌面上找不到支付宝怎么办 苹果手机支付宝找不到了怎么办 微信上充话费没到账怎么办 冲q币不到账怎么办 支付宝冲话费没到帐怎么办 qq实名认证没有银行卡怎么办 微信零钱限额没有银行卡怎么办 qq钱包忘记支付密码怎么办 零钱包密码忘了怎么办 关爱通密码知道卡号忘了怎么办 卡号的密码忘了怎么办 银行卡号密码忘了怎么办 微信超出单月支付限额怎么办 行李箱三位数密码忘记了怎么办 手机忘记4位数密码怎么办 win7登入密码忘记了怎么办 电脑登入密码忘记了怎么办 电脑忘记登入密码怎么办