2009-12-30 30 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)。