繁体   English   中英

多线程/并发问题

[英]Multithreading/Concurrency issue

我正在使用线程编写理发店程序。 目前,我有一个理发师,同时有多个客户。 但是,在第一次运行该程序后,其余客户全都陷入困境。 他们都同时坐下。 有什么我想念的吗? 我的代码是:

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

你有

notify();
wait();

getCut方法的开头,它的作用是:

  • 第一个客户端进入,它调用通知,然后等待
  • 第二个客户端进入,它调用notify-从而唤醒第一个客户端,然后等待
  • 第三个客户端进入,它调用通知-结果第二个客户端唤醒,依此类推

相反,您应该使用notify和wake来阻止特定资源(主席)。

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();
}

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

本示例使用三把椅子,但是您只能使用一个(布尔值)或任何其他数字。 您可以对收银员进行同样的操作。

使用下面的代码作为模板(来自Magee&Kramer的教科书)...

  • ProducerConsumer =理发店
  • 创建大小为1的BarberShop
  • get = GiveCut(理发师“吸引”客户并给客户理发)
  • put = getCut(客户要求理发-即“放入”客户要求的理发)

码:

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);
  }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM