0

对于作业,我必须在 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() 上解除阻塞一个线程?我读到有一个阻塞的队列,但我会在哪里继续引用该队列?

4

2 回答 2

1

在您的等待方法(应该称为等待以外的其他方法)中,您需要检查您的值是否为零,如果为零,则继续等待。这是通过以下方式实现的:

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

您的方法不采用 Semaphore 对象。您只需在 Semaphore 类中使用 value 字段。

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

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

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

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

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

于 2013-03-08T17:50:32.400 回答
0

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

于 2013-03-08T17:45:26.613 回答