Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/362.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 多线程/并发问题_Java_Multithreading_Concurrency_Locking - Fatal编程技术网

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结果,第二个客户端唤醒,依此类推
相反,您应该使用notify和wake来阻止特定的资源(椅子)

在这种情况下,您可以只使用notify(),但如果不同的线程正在等待释放资源并获取资源,那么调用notify可能会唤醒错误的线程。 不要担心在同一时间唤醒太多线程,因为每个线程都会检查资源是否可用,并且只有第一个线程能够获取资源,其余线程将继续等待

本例使用三把椅子,但您只能使用一把(布尔值)或任何其他数字。
你也可以对收银员这样做

使用下面的代码作为模板(来自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);
  }
}