2009-12-30 37 views
0

我有一個針對「操作系統」的項目。我需要用java編寫2個程序...IllegalMonitorException在Java中使用信號量和監視器

  1. 編寫一個程序,用2種方法產生水和氫。方法氧氣產生一種氧氣和方法氫氣產生一種氫氣。當2個氫氣和一個氧氣存在時,H2O產生。我必須用信號量和線程來寫這個。

  2. 用Monitors和Sychronize寫上面的問題。

我所著的一些代碼,這一點,但它給非法監視exeption ...... 請幫我糾正......

這是我的代碼:

// class for implement Thread for oxygen 
public class Thread_O implements Runnable { 

    public void run() { 

     thread t = new thread(); 

     try { 
      t.oxygen(); 
     } catch (InterruptedException ex) { 
      Logger logger = Logger.getLogger(Thread_O.class.getName()); 
      logger.log(Level.SEVERE, null, ex); 
     } 
    } 
} 


// class for implement Thread for Hydrogen 
public class Thread_H implements Runnable { 

    public void run() { 

     thread t = new thread(); 

     try { 
      t.Hydrogen(); 
     } catch (InterruptedException ex) { 
      Logger logger = Logger.getLogger(Thread_H.class.getName()); 
      logger.log(Level.SEVERE, null, ex); 
     } 
    } 
} 

//class for method Oxygen and Hydrogen 
public class thread { 

    Semaphore O = new Semaphore(0, true); 
    Semaphore H = new Semaphore(0, true); 
    Semaphore H2O = new Semaphore(0, true); 
    Semaphore safe = new Semaphore(1, true); 

    public void oxygen() throws InterruptedException { 

     safe.wait(); 

     H.wait(); 
     H.wait(); 

     H2O.release(); 
     H2O.release(); 

     Safe.release(); 
     // System.out.println("O2...!"); 
    } 

    public void Hydrogen() throws InterruptedException { 

     H.release(); 
     H2O.wait(); 

     // System.out.println("H2...!"); 
    } 
} 

並在氧氣按鈕的作用:

Thread th = new Thread(new Thread_O()); 
    th.start(); 
+0

你或許可以期待有用的指向正確的方向,但不是有人完成你的任務。 也許你應該從看文本開始,看起來像你在底部複製並粘貼了相同的文本,你是否留下了一些東西? – Fredrik 2009-12-30 06:41:08

+0

順便說一句,你得到例外的原因是你沒有在等待什麼同步。看看這個:http://www.jchq.net/tutorial/07_03Tut.htm – Fredrik 2009-12-30 06:42:06

+5

緊急情況下,你的意思是你拖延了自己的任務直到最後一分鐘? – 2009-12-30 06:48:01

回答

2

你必須瞭解生產者/消費者機制如何工作。

在這裏,您將有一個消費者線程和兩個生產者。

首先,你將有一個線程生產氧氣,和其他生產氫氣。

那麼,這些分子應該放置在「某處」好嗎?這個「東西」是必須被監控和同步的東西。

所以它應該是這樣的:

class Water { 
    char [] waterMolecule = new char[3]; // <-- synchronize access to this 
    char hydrogen(){ 
     return 'H'; 
    } 
    char oxygen() { 
     return 'O'; 
    } 

    void produce() { 
     Thread t = new Thread(new Runnable() { 
       synchronize(waterMolecule) { 
         waterMolecule[0] = hydrogen(); 
       } 
      }): 
      .... produce the others 


     } 

     void consume() { 
     synchronize watermolecule 
      if waterMolecule is complete 
       create water and clean out the molecule. 
     } 
    } 

這是基本的想法。

只要記住,你將不能生產另一個氧氣顆粒,直到前一個被消耗。

你也必須調用等待在while循環

Here's等候/同步應該如何進行編碼。

Here's一些生產者/消費者樣本。

3

我不打算爲您解碼作業,但當您嘗試在對象上使用wait()而不是​​時,會拋出IllegalMonitorException。因此,要等待叫list對象:

synchronized (list) { 
    try { 
     list.wait(); 
    } catch(Throwable t) { 
     t.printStackTrace(); 
    } 
} 
1

雖然你的功課已經到期,我想提出CyclicBarrier作爲這種情況下的最佳解決方案。 它允許爲不同線程(這裏是:你的分子生產者)提供某種集合,並觸發另一個完成時可運行的執行(這裏:創建h20)。