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()で1つのスレッドのブロックを解除するのかということです。ブロックされたキューがあることを読んでいましたが、そのキューへの参照をどこに保持しますか?

4

2 に答える 2

1

待機メソッド(待機以外の名前で呼び出す必要があります)では、値がゼロであることを確認する必要があります。値がゼロの場合は、待機を続けます。これは、次の方法で実現されます。

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

あなたのメソッドはセマフォオブジェクトを取りません。Semaphoreクラスのvalueフィールドを使用するだけです。

このメソッドは、値が0の間、値が変更されるのを待つことを確認します。したがって、メソッドを呼び出すスレッドは待機する必要があります。それ以外の場合、値がゼロでない場合、スレッドはクリティカルセクションに入る可能性があり、値が再びゼロに達するまでデクリメントされます。これは、スレッドがブロックするときです。

シグナルメソッドは値をインクリメントし、値が変更されたことを待機しているスレッドに通知して、クリティカルセクションに入ることができるかどうかを確認する必要があります。シグナルメソッドは、次のように実装されています。

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

メソッドに使用した名前は、ダイクストラがセマフォに使用した名前に由来しています(混乱した場合に備えて)。

Objectのwaitメソッドと混同されるため、blockingメソッドwaitを呼び出さないでください。

于 2013-03-08T17:50:32.400 に答える
0

wait()/ notify()メソッドの使用を検討してください。これらを呼び出す前に、オブジェクトロックを取得する必要があります。つまり、メソッドを非静的にし、同期済みとしてマークする必要があります

于 2013-03-08T17:45:26.613 に答える