银行业务调度系统的实现

网友投稿 261 2022-09-12

银行业务调度系统的实现

需求:

银行业务调度系统

模拟实现银行业务调度系统逻辑,具体需求如下:

银行内有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 normallist=new ArrayList<>(); public List viplist=new ArrayList<>(); public List 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 normals; public ArrayBlockingQueue vips; public ArrayBlockingQueue quicks; public void produce(){ Random random=new Random(); Random time=new Random(); int i=1; try { while (true) { //产生1-10 int 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 vips, ArrayBlockingQueue normals, ArrayBlockingQueue quicks) { try { while (true) { // do vip final 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 vips, ArrayBlockingQueue normals, ArrayBlockingQueue quicks) { try { while (true) { // do vip final 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 vips, ArrayBlockingQueue normals, ArrayBlockingQueue quicks) { try { while (true) { // do vip final 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 normals = new ArrayBlockingQueue<>(10); final ArrayBlockingQueue vips = new ArrayBlockingQueue<>(10); final ArrayBlockingQueue 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) { / int 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

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:猿大侠:昨天,微信更了10个重磅功能!这次终于有进度条了?
下一篇:分布式锁的进化过程
相关文章

 发表评论

暂时没有评论,来抢沙发吧~