Java 多线程/并发问题
我正在用线程编写一个理发店程序。目前我有一个理发师和多个顾客同时进来。然而,在第一次运行该程序之后,其余的客户都被搞得一团糟。他们都同时坐下。有什么我错过的吗?我的代码是:Java 多线程/并发问题,java,multithreading,concurrency,locking,Java,Multithreading,Concurrency,Locking,我正在用线程编写一个理发店程序。目前我有一个理发师和多个顾客同时进来。然而,在第一次运行该程序之后,其余的客户都被搞得一团糟。他们都同时坐下。有什么我错过的吗?我的代码是: public synchronized void enter(Customer cust) { custList.add(cust); getCut(cust); } public synchronized void getCut(Customer cust) {
public synchronized void enter(Customer cust) {
custList.add(cust);
getCut(cust);
}
public synchronized void getCut(Customer cust) {
try {
notify();
wait();
System.out.println("sit down");
notify();
if (cashier==0) {
cashier++;
wait();
System.out.println("waiting to pay");
notify();
wait();
System.out.println("left the room");
chairs++;
cust.terminate();
}
} catch (InterruptedException ie) {}
}
这是我理发师的一部分:
public synchronized void cut(Barber barb) {
cashier=0;
try {
if(temp){
System.out.println(temp);
temp = false;
notify();
wait(); //wait for the customer to be settled in
System.out.println("go to cus");
notify();
wait();
System.out.println("cut cus hair");
notify();
wait();
if (cashier==1) {
System.out.println("got money");
notify();
cashier--;
barbers++;
}
}
} catch (InterruptedException ie) {}
}
}
public synchronized void goCut(Barber barb) {
cashier=0;
try {
if(temp){
System.out.println(temp);
temp = false;
notify();
wait();
System.out.println("walks to cus");
notify();
wait();
System.out.println("cut hair");
notify()
wait();
if (cashier==1) {
System.out.println("got the money");
notify();
cashier--;
barbers++;
}
}
从oracle站点
注意:始终在测试等待条件的循环中调用wait。不要假设中断是针对您正在等待的特定条件,或者该条件仍然为真
请参阅您似乎在随机使用
通知
和等待
你有
notify();
wait();
在getCut
方法的开头,它所做的是:
- 第一个客户端进入,它调用notify,然后等待
- 第二个客户机进入,它调用notify,从而唤醒第一个客户机,然后等待
- 第三个客户端进入,它调用notify-in结果,第二个客户端唤醒,依此类推
你也可以对收银员这样做 使用下面的代码作为模板(来自Magee&Kramer的教科书)
- ProducerConsumer=理发店
- 创建大小为1的理发店
- get=giveCut(理发师“接过”顾客并给顾客理发)
- put=getCut(客户要求理发,即“puts”客户要求理发)
通知怎么样;等待();方法它们是内置的。它们在同步线程之间来回切换。您是否能够更准确地了解问题发生的位置?要通读所有的代码,而不轻易地在上面花费大量时间,是有点困难的。你能更准确地指出问题出在哪里吗?我觉得这与锁有关。有没有一种方法可以在每位顾客之后完全重新启动理发线?你的等待和通知到处都是。不需要那么复杂。顺便问一下,所有这些方法都在同一个类中吗?另外,想想每种方法都在尝试做什么。您的方法名称是
goCut
,cut
,getCut
-都非常(太?)相似。您可以通过几种方式处理理发师(消费者)和客户(生产者)。例如,理发师可以是一根线,只要理发就可以无限循环(理发店关门时就会停止)。或者,理发师可以在一个或多个顾客等待时产生。您可以创建任意数量的客户线程。
private final Object pChairLock = new Object();
private int pAvaliableChairs = 3;
...
// take the resource
synchronized(pChairLock)
{
// wait until a chair is avaliable
while(pAvaliableChairs == 0)
{
pChairLock.wait();
}
// take sit
pAvaliableChairs--;
}
// now the current thread 'is sitting'
// - it can do some work using the resource
// after finishing, release the resource
synchronized(pChairLock)
{
pAvaliableChairs--;
// notify all waiting thread that resource is available
pChairLock.notifyAll();
}
public class ProducerConsumer {
protected Object[] buf;
protected int count = 0;
protected int size;
public ProducerConsumer(int size) {
this.size = size;
buf = new Object[size];
}
public synchronized void put(Object o) throws InterruptedException {
while (count == size) wait();
buf[count] = o;
++count;
notifyAll();
}
public synchronized Object get() throws InterruptedException {
while (count == 0) wait();
--count;
Object o = buf[count];
buf[count] = null;
notifyAll();
return (o);
}
}