题目描述
模拟银行柜台业务的办理逻辑,去银行办理业务时,银行有固定的柜台数量M。客户来银行办理业务,到达时间随机、业务办理时长随机。客户先取号,再等着排队叫号。为了保证公平,叫号时要按照排队顺序叫,不能插队。可以把柜台看作是消费者,而客户是生产者。为了保存客户的排队状态,需要使用一个先进先出的队列作为缓冲区。客户(生产者)来了以后,就进缓冲区排队。而每个柜台每办理完一个客户的业务,就从缓冲区中取出一个客户继续办理业务。为了真实模拟,我们假设在银行刚开门的时候,有一批排队在银行门口的人。等银行开门后,在某一时间,会有N个人前来银行办理业务。
【设计要求】
1.用程序模拟实现银行业务办理流程,初始的柜台数量,顾客,由手工输入完成。
2.将柜台看作是消费者进程,而客户是生产者进程,程序模拟进程的同步控制过程。
3.程序的输出为银行排队叫号的过程。
银行类
class Bank {
private int M; // 柜台数量
private int N; // 客户数量
private Queue<Integer> queue; // 等待队列
private Customer[] customers;// 客户组
public Bank(int M, int N) {
this.M = M;
this.N = N;
this.queue = new LinkedList<>();
customers = new Customer[N];
for (int i = 0; i < N; i++) {
int arriveTime = new Random().nextInt(60) + 1;
customers[i] = new Customer(arriveTime, new Random().nextInt(10) + 30,(char)('A' + i));
}
for (int i = 0; i < N; i++) {
customers[i].setSort(i);
}
}
}
可以把柜台当做消费者,客户是生产者
消费者和生产者代码
public void produce() throws InterruptedException {
int count = 0;
while (count < N) {
synchronized (this) {
while (queue.size() == M) {
wait();
}
queue.offer(count);
notifyAll();
count++;
}
}
}
public void consume() throws InterruptedException {
int count = 0;
while (count < N) {
synchronized (this) {
while (queue.isEmpty()) {
wait();
}
int customerId = queue.poll();
notifyAll();
count++;
}
}
}
顾客类
class Customer {
private int arrivalTime;
private double serviceTime;
public Character getName() {
return name;
}
private Character name;
private int sort;
public void setSort(int sort) {
this.sort = sort;
}
public Customer(int arrivalTime, double serviceTime,Character name) {
this.arrivalTime = arrivalTime;
this.serviceTime = serviceTime;
this.name = name;
}
public int getArrivalTime() {
return arrivalTime;
}
public double getServiceTime() {
return serviceTime;
}
public int getSort() {
return sort;
}
}
主函数开两个线程分别执行消费者和生产者,模拟银行排队
主方法
public static void main(String[] args) throws InterruptedException {
int M,N;
Scanner e = new Scanner(System.in);
System.out.print("请输入银行柜台数量:");
M = e.nextInt();
System.out.print("请输入客户数量:");
N = e.nextInt();
Bank bank = new Bank(M, N);
Thread producer = new Thread(() -> {
try {
bank.produce();
} catch (InterruptedException e1) {
e1.printStackTrace();
}
});
Thread consumer = new Thread(() -> {
try {
bank.consume();
} catch (InterruptedException e1) {
e1.printStackTrace();
}
});
producer.start();
consumer.start();
producer.join();
consumer.join();
}