繁体   English   中英

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

[英]Semaphore how to block and unblock

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

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

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

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

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

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

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

我为这些方法使用的命名来自用于信号量的名称Dijkstra(以防万一您对它们感到困惑)。

您不应该调用阻塞方法wait,因为它将与Object中的wait方法混淆。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM