使用监视器概念实现信号量

时间:2012-03-07 21:25:37

标签: java multithreading operating-system semaphore monitor

我正在尝试使用Java中的监视器概念来实现信号量。即实现弱计数信号量的Java类(使用方法init,signal和wait)

有人可以告诉我这个班级是否正确(如果没有问题):

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

如果这是正确的,有人可以告诉我如何测试课程。

3 个答案:

答案 0 :(得分:1)

应该是这样的(使用while,而不是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--;
    }
}

如何测试:

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();
            }
        }
    }
}
  • 没有信号量,Exception会一直抛出(差不多)。
  • 使用建议的信号量,不会抛出异常。
  • 使用您的信号量,有时会抛出异常(但不是没有信号量)。

您的信号量问题是:

  1. 主题1有一个锁
  2. 主题2和主题3是wait() ing
  3. 主题1调用notifyAll()
  4. 线程2和3同时进入临界区,这是不好的:)

答案 1 :(得分:0)

我看到的唯一问题是这部分:

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

    counter--;

如果线程在等待时被中断,它将简单地退出if语句,将计数器减少到0以下然后你的信号量系统出现严重错误,因为现在没有人会被迫等待,因为{{1} }小于0.

您可能应该将counter替换为if,以防万一。

答案 2 :(得分:-1)

只是一个问题:为什么不使用java标准? http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Semaphore.html