Implementing semaphores using the monitor concept

I am trying to implement semaphores using the monitor concept in Java. Ie Java class implementing weak counting semaphore (using init, signal and wait methods)

Can someone tell me if this class is correct (if not the problem):

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--;
    }
}

      

If this is correct, can someone give me an idea of ​​how I can inspect the class.

+3


source to share


3 answers


It should be like this (with while

, not if

):

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--;
    }
}

      

How to check:

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();
            }
        }
    }
}

      



  • Without a semaphore, an exception is thrown all the time (almost).
  • With the proposed semaphore, no Exception is thrown.
  • With your semaphore, an Exception is sometimes thrown (but not as often as without semaphores).

The problem with your semaphore is:

  • Thread 1 has a lock
  • stream 2 and stream 3 wait()

    ing
  • thread 1 calls notifyAll()

  • thread 2 and 3 enter the critical section at the same time, which is bad :)
+1


source


Well, the only problem I see is this part:

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

    counter--;

      



If the thread is interrupted while it is waiting, it will just exit the instruction if

, decrement the counter below 0, and then your semaphore system will be terribly wrong as no one will be forced to wait now because it is counter

less than 0.

You should probably be replaced if

on while

just in case.

0


source


Just a question: why don't you use the java standard? http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Semaphore.html ?

-1


source







All Articles