1

プログラムで何らかの順序を強制するためにセマフォを使用しています。メインスレッドと、メインスレッドで作成されたいくつかのサブスレッドがあります。すべてのステップのメインスレッドでクロックが刻み込まれ、その後、各サブスレッドを1つずつ実行します。サブスレッドの順序は重要ではありませんが、すべてのサブスレッドを各ステップで実行する必要があります (各ステップで 1 回だけ実行します)。私はこのコードを書きましたが、問題は、場合によっては、サブスレッドの 1 つのステップで複数回実行され、他のスレッドに実行の機会が与えられないことです?!

メインスレッド:

     Semaphore okToTick = new Semaphore(3);
     Semaphore okToWork = new Semaphore(0, true);

     int i = 0;

     new TestClass2(0, okToTick, okToWork);
     new TestClass2(1, okToTick, okToWork);
     new TestClass2(2, okToTick, okToWork);

     while(true){

        okToTick.acquire(3);

        System.out.printf("\clock : %s\n", i++);


        okToWork.release(3);

     }

サブスレッド用の run():

    semaphores here, passed by cnstr() 
    ID = //passed in by cnstr()    
    isBusy = false; 
    ----------------------------------
    try{
        while(true){

            okToWork.acquire();

            if(!isBusy){
                System.out.println("inside sub " + ID);
                isBusy = true;
            }


            okToTick.release();

        }

    }
    catch(Exception e){}

この結果が欲しい:

  clock : 0
  inside sub 1
  inside sub 0
  inside sub 2

  clock : 1

  clock : 2
  ...

しかし、時々私はこれを得る:

  clock : 0
  inside sub 1

  clock : 1
  inside sub 0
  inside sub 2

  clock : 2
  ...
4

3 に答える 3

7

CyclicBarrierを探していると思います:

一連のスレッドが互いに共通のバリア ポイントに到達するのをすべて待機できるようにする同期支援。CyclicBarriers は、相互に時折待機する必要がある固定サイズのスレッドのパーティを含むプログラムで役立ちます。バリアは、待機中のスレッドが解放された後に再利用できるため、サイクリックと呼ばれます。

于 2012-12-22T13:20:51.947 に答える
1

あなたの場合、1 つのスレッドは 、他のスレッドがスピンアップする機会を得る前に、複数回取得okToWorkおよび解放できます。okToTickスレッド番号 1人で3回までできる okTowork.acquire()->okToTick.release()他の人より先に。

また、フラグinside sub xをリセットしないため、スレッドごとに 1 回だけ出力します。isBusy

それらを区別する必要があり、 a を使用してそれを行う最も簡単な方法は、各スレッドSemaphoreに異なる a を与えることです。okToTick Semaphore

于 2012-12-22T13:47:50.530 に答える
0

問題は、「サブスレッド」がセマフォから複数の許可を取得している可能性があり、「サブスレッド内」の出力は1回しか出力されないため、出力でそれを認識していないことです(if(!isBusy)周囲を削除しました)。各「サブスレッド」が複数の許可を取得したくない場合は、外側のwhile(true)ループを削除します。

    okToWork.acquire();

    //if(!isBusy){ Removed to show when this sub-thread is actually acquiring permits
        System.out.println("inside sub " + ID);
    //    isBusy = true;
    //}


    okToWork.release();
于 2012-12-22T13:41:16.080 に答える