首页 > 其他 > 详细

银行业务调度系统的实现

时间:2017-02-22 13:39:43      阅读:135      评论:0      收藏:0      [点我收藏+]
需求:
银行业务调度系统


模拟实现银行业务调度系统逻辑,具体需求如下:
 银行内有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-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 {


	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 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() {
				doVIP(threadPool, Windows, vips, normals, quicks);
			}
		});


		threadPool.execute(new Runnable() {
			public void run() {
				doQuick(threadPool, Windows, vips, normals, quicks);
			}
		});


		threadPool.execute(new Runnable() {
			public void run() {
				doNomal(threadPool, Windows, vips, normals, quicks);
			}
		});


		threadPool.execute(new Runnable() {
			public void run() {


				try {
					while (true) {
						// http://blog.csdn.net/yingzishizhe/article/details/8769907
						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();
				}


			}
		});


	}


	/**
	 * @param threadPool
	 * @param Windows
	 * @param vips
	 * @param normals
	 * @param quicks
	 */
	private static void doQuick(ExecutorService threadPool, WindowList Windows, ArrayBlockingQueue<Consumer> vips,
			ArrayBlockingQueue<Consumer> normals, ArrayBlockingQueue<Consumer> 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
	 */
	private static void doNomal(ExecutorService threadPool, WindowList list, ArrayBlockingQueue<Consumer> vips,
			ArrayBlockingQueue<Consumer> normals, ArrayBlockingQueue<Consumer> 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
	 * 
	 */
	private static void doVIP(ExecutorService threadPool, WindowList list, ArrayBlockingQueue<Consumer> vips,
			ArrayBlockingQueue<Consumer> normals, ArrayBlockingQueue<Consumer> 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();
		}


	}


}


银行业务调度系统的实现

原文:http://blog.csdn.net/dlf123321/article/details/56481207

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!