2012-03-07 15 views
3

Javaでモニターの概念を使用してセマフォーを実装しようとしています。このクラスが正しいかどう弱いカウンティングセマフォを実装つまりJavaクラス(使用方法は、信号を初期化して待つ)モニターの概念を使用してセマフォーを実装してください

は、誰かが(問題が何であるかではない場合)を教えてもらえます:

class MyMonitor 
{ 
    int counter = 0; 

    //init 
    public MyMonitor(int init) 
    { 
     counter = init; 
    } 

    //Signal 
    public synchronized void S() 
    { 
     counter++; 
     notify(); 
    } 

    //Wait 
    public synchronized void W() 
    { 
     if(counter == 0) 
     { 
      try 
      { 
       wait(); 
      } 
      catch(InterruptedException e) { } 
     } 

     counter--; 
    } 
} 

これがあれば正しい、誰かが私にどのようにクラスをテストできるかのアイデアを与えることができます。

答えて

0

まあ私が見る唯一の問題は、この部分です:

if(counter == 0) 
    { 
     try 
     { 
      wait(); 
     } 
     catch(InterruptedException e) { } 
    } 

    counter--; 

スレッドが中断された場合は待機している間、それは単に、if文を終了0未満にカウンタをデクリメントしてからセマフォシステムは恐ろしく行くだろうcounterあなたはおそらく、念のために、whileifを置き換える必要が0未満

あるので、今誰も待つことを余儀なくされませんので、間違っています。

+1

もう一方のr easonは '偽の弱点 'を使用します。 – zch

+0

@zch:良い点。 – Tudor

1

それは(ifを、whileではない)、このようにする必要があります:どのようにテストへ

class YourMonitor 
{ 
    int counter = 0; 

    //init 
    public MyMonitor(int init) 
    { 
     counter = init; 
    } 

    //Signal 
    public synchronized void S() 
    { 
     counter++; 
     notifyAll(); 
    } 

    //Wait 
    public synchronized void W() throws InterruptedException 
    { 
     while (counter <= 0) 
     { 
      wait(); 
     } 

     counter--; 
    } 
} 

:セマフォなし

public class TestYourSemaphore 
{ 
    private static final int CNT = 100000; 

    private int x = 0; 
    private YourSemaphore s = new YourSemaphore(); 

    public void run() throws InterruptedException 
    { 
     Thread t1 = new Thread(new MyRunnable()); 
     Thread t2 = new Thread(new MyRunnable()); 
     Thread t2 = new Thread(new MyRunnable()); 

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

     t1.join(); 
     t2.join(); 
     t3.join(); 


     // Verify, that the X has correct value 
     if (x != 3 * CNT) 
     { 
      throw new RuntimeException("Race condition error!"); 
     } 
     System.out.println("Finished"); 
    } 

    private class MyRunnable implements Runnable 
    { 
     @Override 
     public void run() 
     { 
      for (int i = 0; i < CNT; i++) 
      { 
       //un-comment to use Semaphores 
       //s.enter(); 
       x = x + 1; 
       //s.leave(); 
      } 
     } 
    } 
} 
  • は、例外はすべての時間をスローされます(ほとんど) 。
  • 推奨セマフォを使用すると、例外はスローされません。
  • セマフォを使用すると、例外がスローされることがあります(ただし、セマフォなしの場合はそうではありません)。

あなたのセマフォの問題点は次のとおりです。

  1. スレッド1は、ロック
  2. スレッド2とスレッド3はwait()ありました同時に
  3. スレッド1つの通話notifyAll()
  4. スレッド2と3をINGのクリティカルセクションに入ります。これは悪いです。
+0

notify()をnotifyAll()に置き換えた理由は分かりません。 notifyAll()がなければ、問題は発生しません。なぜなら、あなたはちょうど1スレッドを目覚めさせるからです。別のコメントに記述されている偽の起床を考慮しても、notifyAll()の理由はありません。 –

関連する問題