并发编程 出纳-顾客模型 仿真练习

本文介绍了一个银行服务系统的仿真模型,该模型模拟了顾客随机到达、排队等待及被服务的过程,并能够根据顾客数量动态调整服务窗口的数量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这个仿真模型包括如下几个对象:

顾客: 随机的时间间隔出现顾客,每个顾客办理业务的时间也是随机。顾客会排队办理业务。

出纳: 每次选取排在最前面的顾客进行服务,服务时间由顾客的业务时间而定。

出纳经理: 每隔一段时间,查看顾客排队的人数,排队的人多就增加出纳窗口,排队人少的话,就减少出纳窗口,让出纳休息。


通过调整这个模型的参数:

1.顾客出现的时间间隔
2.各项业务办理的时间

可以估算出柜台大致需要多少个出纳。



package test.thread;

import static java.lang.System.out;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.PriorityBlockingQueue;
import java.util.concurrent.TimeUnit;

public class SimulatorTeller {

public static void main(String args[]){
BlockingQueue<Customer> customerQueue=new LinkedBlockingQueue();;
PriorityBlockingQueue<Teller> tellerRestQueue=new PriorityBlockingQueue();
PriorityBlockingQueue<Teller> tellerWorkQueue=new PriorityBlockingQueue();
ExecutorService se=Executors.newCachedThreadPool();
se.execute(new CustomerGenerator(customerQueue));
se.execute(new TellerManager(customerQueue,tellerRestQueue,tellerWorkQueue,se));
}
}

class Customer{
static int count=0;
final int id=count++;
final int serviceTime=(int)(5000* Math.random());
}

class CustomerGenerator implements Runnable{
private BlockingQueue<Customer> customerQueue;
public CustomerGenerator(BlockingQueue<Customer> customerQueue) {
this.customerQueue = customerQueue;
}
public void run() {
try {
while(!Thread.interrupted()){
customerQueue.offer(new Customer());
TimeUnit.MILLISECONDS.sleep((long)(Math.random()*1000));
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

class Teller implements Runnable, Comparable<Teller>{
static int count=0;
final int id=count++;
private BlockingQueue<Customer> customerQueue;
private boolean canRest=false;
private int servedCount=0;
public Teller(BlockingQueue<Customer> customerQueue) {
this.customerQueue = customerQueue;
}

public void takeABreak(){
out.println("Teller#"+id+" have served "+servedCount+" customer, take a break now.");
this.canRest=true;
servedCount=0;
}

public synchronized void goBackToWork(){
out.println("Too many customer waiting, Teller#"+id+" go back to work.");
this.canRest=false;
this.notify();
}

public void run() {
try {
while (!Thread.interrupted()) {
Customer c=customerQueue.take();
TimeUnit.MILLISECONDS.sleep(c.serviceTime);
synchronized(this){
servedCount++;
out.println("Teller#"+id+" serverd customer#"+c.id);
if(canRest){
wait();
}
}
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

//serverCount多的Teller优先获得休息权力
public int compareTo(Teller o) {
return this.servedCount < o.servedCount ? 1
: this.servedCount > o.servedCount ? -1 : 0;
}

}


class TellerManager implements Runnable{

private BlockingQueue<Customer> customerQueue;
private PriorityBlockingQueue<Teller> tellerRestQueue;
private PriorityBlockingQueue<Teller> tellerWorkQueue;
private ExecutorService se;

public TellerManager(BlockingQueue<Customer> customerQueue,
PriorityBlockingQueue<Teller> tellerRestQueue,
PriorityBlockingQueue<Teller> tellerWorkQueue, ExecutorService se) {
this.customerQueue = customerQueue;
this.tellerRestQueue = tellerRestQueue;
this.tellerWorkQueue = tellerWorkQueue;
this.se = se;
}

public void run() {
try {
while (!Thread.interrupted()) {
makeAjustMent();
TimeUnit.MILLISECONDS.sleep(2000l);
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

private void makeAjustMent() {
try {
out.println("Customer["+customerQueue.size()+"]/TellerWorker["+tellerWorkQueue.size()+"]/TellerRest["+tellerRestQueue.size()+"]");
if (tellerWorkQueue.size() == 0&&tellerRestQueue.size() == 0) {
assignNewTeller();
} else if (customerQueue.size() / tellerWorkQueue.size() > 2) {
if(tellerRestQueue.size()>0){
Teller t = tellerRestQueue.take();
t.goBackToWork();
tellerWorkQueue.put(t);
}else{
assignNewTeller();
}
}else if (customerQueue.size() / tellerWorkQueue.size() < 2) {
Teller t=tellerWorkQueue.take();
t.takeABreak();
tellerRestQueue.put(t);
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

private void assignNewTeller(){
Teller t = new Teller(customerQueue);
tellerWorkQueue.add(t);
se.execute(t);
}

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值