信号量如何阻止和解除阻塞

时间:2013-03-08 17:40:08

标签: java signals block semaphore wait

对于作业,我必须在Java中创建计数信号量。到目前为止,我已经创建了这个裸骨类

public class Semaphore {
    int value;

    public Semaphore(int value) {
        this.value = value;
    }

    public static void wait(Semaphore s) {
        s.value--;
        if (s.value < 0) {
            // block
        }
    }

    public static void signal(Semaphore s) {
        s.value++;
        if (s.value <= 0) {
            // unblock one process that is blocked on semaphore
        }

    }   
}

现在我感到困惑的是我如何阻止wait(),反之如何解锁signal()上的一个线程?我正在读取有一个被阻塞的队列,但我会在哪里继续引用该队列?

2 个答案:

答案 0 :(得分:1)

在你的等待方法中(除了等待之外应该被称为别的东西),你需要检查你的值是否为零,如果它是零,你只需要等待。这可以通过以下方式实现:

public synchronized void P() throws InterruptedException 
{
    while (value == 0) 
    {
        wait();
    }
    value--;
}

您的方法不接受Semaphore对象。您只需使用Semaphore类中的值字段。

该方法检查当值为0时,它等待更改值。因此,调用方法的线程必须等待。否则,如果该值不为零,则线程可以进入其临界区,并且该值将递减,直到它再次达到零,即线程阻塞时。

您的信号方法需要递增值,并通知正在等待值已更改的线程,以查看它是否可以进入其临界区。信号方法实现如下:

public synchronized void V() 
{
    value++;
    notify();
}

我用于方法的命名来自Dijkstra用于信号量的名称(以防你被它们弄糊涂)。

你不应该调用阻塞方法等待,因为它会与Object的wait方法混淆。

答案 1 :(得分:0)

看看使用wait()/ notify()方法。在调用它们之前需要获取对象锁。这意味着你必须使方法非静态并将它们标记为同步