package bank;
/**
* This class is used for ...
* @author dlf([email protected])
* @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([email protected])
* @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([email protected])
* @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([email protected])
* @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([email protected])
* @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();
}
}
}
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([email protected])
* @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) {
// 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();
}
}
});
}
}
最后的打印出来的信息如下:
产生第1个客户,他是快速用户
现在活跃的线程数量为: 5
现在排队的人数为:0
5号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