1

私のアプリケーションでは、重要なセッションでは 1 種類のスレッドのみが処理されていることを確認する必要があります。特定のタイプのスレッド数が指定されておらず、「大きい」可能性があります。私は簡単な解決策を持ってきました:

MutableInt a,b,c;
Semaphore mutex;

void enterA() {
    while (true) {
        mutex.acquire();
        if (b.intValue() == 0 && c.intValue() == 0) {
            a.increase();
            break;
        }
        mutex.release();
    }
}

void exitA() {
    while(true) {
        mutex.acquire();
        a.decrease();
        mutex.release();
    }
}

私は例外処理をスキップしており、B&C の部分は単にコピーして貼り付けるだけです。

期待どおりに動作します (スレッド スタベーションの可能性は問題ありません) が、生成される負荷が大きすぎます。スレッドは常にカウンターをチェックしています。別の解決策があると思いますが、例が思いつきません。

4

1 に答える 1

1

あなたのソリューションが問題の一部であるかどうかはわかりませんが、現状ではAtomicInteger、ロックせずにすべてのインクリメントなどを処理するハンドルに移動することをお勧めします。

より複雑な場合はAtomicReference、いくつかのアキュムレータ クラスで使用することを検討し、compareAndSet(...)メソッドを使用してアトミックに更新する必要があります。

たとえば、3 つの整数をMutableIntsクラスに格納して、次のようにすることができます。

final AtomicReference<MutableInts> reference =
     new AtomicReference<MutableInts>(new MutableInts(0, 0, 0));
...
do {
   MutableInts ints = reference.get();
   // increment the ints properly which should generate a new MutableInts class
   // it should _not_ make changes to `ints` itself
   MutableInts newInts = ints.mutateSomehow(...);
   // this spins in case some other thread updated it before us here
} while (!reference.compareAndSet(ints, newInts));

そのため、これを達成するために使用できる呼び出しが制限されているようです。その他の代替手段を次に示します。

  • 各スレッドは独自のデータを更新し、ときどき (または処理の最後に) 中央のカウンターと同期します。同じロックですが、それほど頻繁に行うことはありませ
  • 各スレッドはスレッドごとvolatileのカウンターを更新でき、ポーリング スレッドはカウンターを読み取り、中心的な情報を更新できます。volatile許可されているかどうかは不明です。
于 2013-06-12T15:40:02.857 に答える