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.
source to share
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 :)
source to share
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.
source to share
Just a question: why don't you use the java standard? http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Semaphore.html ?
source to share