2013-04-20 56 views
0

我寫了一個示例程序來演示我的問題。 有一個酒保線程和三個客戶線程。 它們一旦創建就同時運行。 酒保是爲每位顧客提供飲料。爲什麼我的release()方法不會喚醒我的實例?

我的問題是Bartender類run()方法中的wait()方法從不喚醒。 我曾打算在每個Customer類的run()方法中使用release()方法來喚醒它,但它似乎沒有工作。它永遠不會喚醒。

我該如何解決這個問題? 感謝任何可以提供建議或代碼片段的人。

import java.util.concurrent.Semaphore; 
import java.util.logging.Level; 
import java.util.logging.Logger; 

public class Bar { 

    Semaphore serving; 
    boolean isServing = false; 

    public static void main(String[] args) { 
     Bar bar = new Bar(); 
     bar.run(); 
    } 

    public void run() { 
     serving = new Semaphore(1); 
     Thread bartender = new Thread(new Bartender()); 
     bartender.start(); 
     threadSleep(1000); 

     Thread customer1 = new Thread(new Customer()); 
     customer1.start(); 
     threadSleep(2000); 
     Thread customer2 = new Thread(new Customer()); 
     customer2.start(); 
     threadSleep(2000); 
     Thread customer3 = new Thread(new Customer()); 
     customer3.start(); 
    } 

    public void threadSleep(int time) { 
     try { 
      Thread.sleep(time); 
     } catch (InterruptedException ex) { 
      Logger.getLogger(Bar.class.getName()).log(Level.SEVERE, null, ex); 
     } 
    } 

    public class Bartender implements Runnable { 
     public void run() { 
      while (true) { 
       if (serving.availablePermits() == 0) { 
        synchronized (this) { 
         try { 
          System.out.println("Waiting for Customer notify"); 
          wait(); 
          System.out.println("Serve drink"); 
         } catch (InterruptedException ex) { 
          Logger.getLogger(Bar.class.getName()).log(Level.SEVERE, null, ex); 
         } 
        } 
       } 
      } 
     } 
    } 

    public class Customer implements Runnable { 
     private boolean customerServed = false; 

     public void run() { 
      if (!customerServed) { 
       synchronized (this) { 
        try { 
         serving.acquire(); 
         if (serving.availablePermits() == 0 && !serving.hasQueuedThreads()) { 
          notify(); 
          isServing = true; 
          System.out.println("Customer: Recieves drink"); 
          customerServed = true; 
          serving.release(); 
          isServing = false; 
         } 
        } catch (InterruptedException ex) { 
         Logger.getLogger(Bar.class.getName()).log(Level.SEVERE, null, ex); 
        } 
       } 
      } 
     } 
    } 
} 

回答

2

class Bartenderclass Customer

變化synchronized (this) {synchronized (Bar.this) {

變化wait()Bar.this.wait()

變化notify()Bar.this.notify()

因爲2 this指的是不同的對象,Bartender從不醒來。並且因爲兩個Bar.this指的是同一個對象,所以Bartender會醒來!

+0

謝謝 我做了你的更改,但這導致在運行時引發異常。 java.lang.IllegalMonitorStateException \t at java.lang.Object.notify(Native Method) 任何想法是什麼造成這種情況? – James 2013-04-20 05:25:17

+0

@詹姆斯我錯誤地忘記了一些東西。我已經修好了。 – johnchen902 2013-04-20 05:26:10

+0

神奇,它的作品。非常感謝你的幫助。 – James 2013-04-20 05:29:52

相關問題