2014-03-29 65 views
1

我有點難住。下面幾乎是從A simple scenario using wait() and notify() in java複製和粘貼。Java方法NotifyAll()不起作用?

據我的理解,這個Java程序應該在屏幕上打印yumyum..,但事實並非如此。我在Eclipse中爲Mac OS X.任何想法我做錯了什麼?

public class Main { 
    public static void main(String[] args) { 
     MyHouse house = new MyHouse(); 
     house.eatPizza(); 
     house.pizzaGuy(); 

    } 
} 

class MyHouse extends Thread { 

    private boolean pizzaArrived = false; 

    public void eatPizza() { 
     synchronized (this) { 
      while (!pizzaArrived) { 
       try { 
        wait(); 
       } catch (InterruptedException e) { 
       } 
      } 
     } 
     System.out.println("yumyum.."); 
    } 

    public void pizzaGuy() { 
     synchronized (this) { 
      this.pizzaArrived = true; 
      notifyAll(); 
     } 
    } 
} 

回答

2

嘗試......

public class Main { 

    public static void main(String[] args) { 
     MyHouse house = new MyHouse(); 
     house.start(); 
//  house.eatPizza(); 
     // Halt main thread momentarily to delay Mr Pizza Guy 
     try { Thread.sleep(3000); } catch(Exception e) {} 
     house.pizzaGuy(); 

    } 
} 

class MyHouse extends Thread { 

    private boolean pizzaArrived = false; 
    private Object lock = new Object(); 

    @Override 
    public void run() { 
     eatPizza(); 
    } 

    public void eatPizza() { 
     synchronized (lock) { 
      while (!pizzaArrived) { 
       try { 
        System.out.println("Waiting for Pizza guy"); 
        lock.wait(); 
       } catch (InterruptedException e) { 
       } 
      } 
      System.out.println("Pizza arrived!!!"); 
     } 
     System.out.println("yumyum.."); 
    } 

    public void pizzaGuy() { 
     synchronized (lock) { 
      this.pizzaArrived = true; 
      lock.notifyAll(); 
     } 
    } 
} 
+0

這是完美的匿名。謝謝! –

+0

正確,不要使用'synchronized(this)',這會鎖定主對象,並且會阻塞主線程。嘗試將鎖定在虛擬對象上,我會工作得很好。 – Akash5288

3

你有一個線程。單線程將無限期地wait(它需要由另一個線程通知)。嘗試創建另一個線程,其中一個將eatPizza()一會pizzaGuy

+0

唉,仍然沒有工作。這裏是我更新的主要:

 public class Main { \t public synchronized static void main(String[] args) { \t \t MyHouse house = new MyHouse(); \t \t house.eatPizza(); \t \t MyHouse house1 = new MyHouse(); \t \t house1.pizzaGuy(); \t } } 

+0

@MartynChamberlin更糟。現在你仍然只有一個線程,並調用2個不同對象的同步方法。有一個線程,你需要在某個Thread實例上調用'start()'。否則,一切都由主線程執行。 –

+0

@JBNizet你介意發表一個這樣的例子嗎?在我的主要方法中?我正在調用.start()(忘了這一點,謝謝),它仍然無法正常工作。對不起,我的頭很厚。 –

0

嘗試下面的代碼工作正常。

公共類WaitNotify {

private static int i = 1; 
private static boolean flag = false; 
static Object obj = new Object(); 

public static void main(String[] args) { 

    Thread t1 = new Thread(new Runnable(){ 

     @Override 
     public void run() { 
       while(i<10){ 
        synchronized (obj) { 
         try { 
          if(i%2 == 0){ 
           obj.wait(); 
          } 
          System.out.println("t1 -> " + i++); 
          obj.notify(); 

          Thread.currentThread().sleep(500); 

         } catch (InterruptedException e) { 
          // TODO Auto-generated catch block 
          e.printStackTrace(); 
         } 
        }      
       } 
     }   
    }); 

    Thread t2 = new Thread(new Runnable(){ 

     @Override 
     public void run() { 
      while(i<10){ 
       synchronized (obj) { 
        try { 
         if(i%2 != 0){ 
          obj.wait(); 
         } 
         System.out.println("t2 -> " + i++); 
         obj.notify(); 
         Thread.currentThread().sleep(500); 
        } catch (InterruptedException e) { 
         // TODO Auto-generated catch block 
         e.printStackTrace(); 
        } 
       }      
      } 
     }   
    }); 

    t1.start(); 
    t2.start(); 

    try { 
     t1.join(); 
     t2.join(); 
    } catch (InterruptedException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 

} 

}