对于作业,我必须在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()上的一个线程?我正在读取有一个被阻塞的队列,但我会在哪里继续引用该队列?
答案 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()方法。在调用它们之前需要获取对象锁。这意味着你必须使方法非静态并将它们标记为同步