嗨,我正在研究睡觉的理发师问题。当他们到达时增加了优先顾客,他们走在前面,他们是下一个理发师。
我正在使用linkedlist
,如果我看到优先客户,我将他列入列表的开头,如果客户不是优先考虑,他会到列表的末尾。然后我调用wantHaircut方法获取列表的第一个元素。
我的问题是客户按照他们到达的顺序进行处理,优先客户必须等待。这是所有发生的代码。我的错误是什么?感谢
public void arrivedBarbershop(Customer c){
if(waiting < numChairs && c.isPriority()){
System.out.println("Customer " + c.getID() + ": is a priority customer - SITTING -");
mutex.up();
customer_list.addFirst(c);
}
else if(waiting >= numChairs && c.isPriority()){
System.out.println("Customer " + c.getID() + ": is a priority customer - STANDING -");
mutex.up();
customer_list.addFirst(c);
}
else if(waiting < numChairs && !c.isPriority()){
waiting++;
System.out.println("Customer " + c.getID() + ": arrived, sitting in the waiting room");
customer_list.addLast(c);
customers.up(); // increment waiting customers
}
else if(waiting >= numChairs && !c.isPriority()) {
System.out.println("Customer " + c.getID() + ": went to another barber because waiting room was full - " + waiting + " waiting");
mutex.up();
}
if(!customer_list.isEmpty()){
this.wantHairCut(customer_list.removeFirst());
}
}
public void wantHairCut(Customer c) {
mutex.up();
barber.down(); // waits for being allowed in barber chair
System.out.println("Customer " + c.getID() + ": getting haircut");
try {
/** haircut takes between 1 and 2 seconds **/
Thread.sleep(Barbershop.randomInt(1, 2) * 1000);
} catch (InterruptedException e) { }
System.out.println("Barber: finished cutting customer " + c.getID() + "'s hair");
c.gotHaircut = true;
cutting.up(); // signals cutting has finished
/** customer must pay now **/
this.wantToCashout(c);
}
答案 0 :(得分:1)
您必须使用同步集合:
Collections.synchronizedList(List<Object> list)
此方法返回基于参数列表的同步List实例
答案 1 :(得分:0)
我很确定逻辑错误就在这里:
if(waiting < numChairs && c.isPriority()){
System.out.println("Customer " + c.getID() + ": is a priority customer - SITTING -");
mutex.up();
customer_list.addFirst(c);
}
else if(waiting >= numChairs && c.isPriority()){
System.out.println("Customer " + c.getID() + ": is a priority customer - STANDING -");
mutex.up();
customer_list.addFirst(c);
}
是的,避免复制/粘贴编程!
答案 2 :(得分:0)
无论何时修改列表,都应该将该代码放在同步块上。
一种方法:
synchronized(customer_list) {
customer_list.addFirst(c);
}
另一个,所以你不必在整个地方编码:
public synchronized void addCustomerAtStart(Customer c) {
customer_list.addFirst(c);
}
然后替换该功能。
当你执行customer.up()时,看起来它也需要同步,否则你可能会遇到很多不一致的行为。
你甚至不需要使用“mutex.up()” 提示:如果必须同步线程,您可能需要查看CountDownLatch,它非常易于使用,可以稳定地用于线程同步。
答案 3 :(得分:0)
您的代码会将客户添加到列表中(开始或结束),然后从列表中删除客户。该列表最多只包含一个客户,因此客户按其添加顺序进行处理。