我试图模拟银行的服务。到目前为止,我可以随机地随机生成客户,如果他们不忙,收银员将为他们服务。当模拟应该结束时,我的问题就来了......它不会。客户不再生成,但收银员一直在等待客户。我尝试了不同的方法,但都失败了。这是尝试不同解决方案之前的代码。
这是CustomerGenerator:
@Override
public void run() {
while (currentTime != openTime) {
double accept = Math.random();
if (accept >= 0.6) {
addCustomerToQueue();
System.out.println("Customer in line.");
} else {
System.out.println("Waiting for a customer.");
}
try {
currentTime += 1000;
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
}
}
private synchronized void addCustomerToQueue() {
Customer customer = new Customer(placeInLine + 1);
this.customerLinkedList.add(customer);
placeInLine++;
notify();
}
synchronized Customer getNextCustomer() throws InterruptedException {
notify();
while (customerLinkedList.size() == 0) {
wait();
}
return customerLinkedList.poll();
}
这是收银员:
@Override
public void run() {
try {
while (true) {
Customer customer = generator.getNextCustomer();
int customerServingNumber = customer.getServingNumber();
double customerServingTime = customer.getServingTime();
System.out.println(cashierName + " serving " + customerServingNumber + " for " + getServingTime(customerServingTime));
Thread.sleep(customerServingNumber * 1000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
答案 0 :(得分:1)
Cashier
线程仅在被中断后终止(在Thread.interrupt
直接调用或通过ExecutorService.shutdownNow
之类的其他函数调用后)。您必须安排线程被中断,如果设置了某个条件(如布尔标志)则中断,或者传入一个特殊的空对象,告诉线程自己退出。
虽然您可以使用wait
和notify
对此进行建模,但使用producer-consumer实施BlockingQueue
工作流程更为简单。将生成器线程put
元素放入队列,并从队列中获取消费者线程take
。当没有更多元素要生成时,在队列中添加一个特殊的空对象,作为消费者退出的信号,或者只是中断线程。
答案 1 :(得分:1)
如 jspcal :
所述Cashier线程仅在被中断后终止(在Thread.interrupt直接调用或通过ExecutorService.shutdownNow等其他函数调用后发生。
有时 - 是的,您可以使用wait
和notify
来运行您的系统,或Thread.interrupt()
来结束您的主题 - "停止线程" 解决此问题的方法是将Cashier
主循环从while(true)
更改为while(condition)
。收银员接受时这种情况应该是真的,而Cashier
不接受这种情况是假的。
答案 2 :(得分:0)
这很有用,但我想知道它是否是一个合适的解决方案:
CustomerGenerator:
synchronized Customer getNextCustomer() throws InterruptedException {
notify();
while (customerLinkedList.size() == 0) {
if (currentTime == openTime){
return null;
}
wait();
}
return customerLinkedList.poll();
}
收银员:
@Override
public void run() {
try {
Customer customer = generator.getNextCustomer();
while (customer != null) {
int customerServingNumber = customer.getServingNumber();
double customerServingTime = customer.getServingTime();
System.out.println(cashierName + " serving " + customerServingNumber + " for " + getServingTime(customerServingTime));
customer = null;
Thread.sleep(customerServingNumber * 1000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}