5

T というスレッド クラスを作成します。

私の目的は、一度に 1 つのスレッド オブジェクトだけが実行されるようにすることです。

そのため、スレッド オブジェクトが呼び出されると、BUSY というブール値のフラグがチェックされます。

私の質問は、違いは何ですか

private static AtomicBoolean BUSY = new AtomicBoolean(false);

private static boolean BUSY = false;

「静的」を使用すると、すべてのオブジェクトが1つのBUSYブール変数のみをチェックするため、1つのスレッドオブジェクトのみが実行されていることが確認されると思いました。

4

4 に答える 4

8

同等のソリューションを得るには、少なくとも boolean 変数volatileと AtomicBoolean 変数を作成する必要があります。finalそれを行った後、ユースケースに違いはありません。

1 つの読み取りアクションと 1 つの書き込みアクションをアトミックな全体に結合するAtomicBooleangetAndSetまたはメソッドを使用すると、違いが生じます。compareAndSetvolatile

于 2012-08-20T09:29:12.257 に答える
2

booleanと を適切な同期で使用できます(および を作成するvolatile) と、必要なものを実現できます。
しかし、 を使用するAtomicBooleanことで、自分で同期用のコードを書く必要なく、現在の値をアトミックにチェックできます。

于 2012-08-20T09:43:29.227 に答える
0

の便利な機能は、AtomicBooleanBUSYがfalseの場合にのみ単一のスレッドを続行できるようにすることですが、他のスレッドを続行させないことです。

private static AtomicBoolean BUSY = new AtomicBoolean(false);

public void doWork(){
  if(BUSY.compareAndSet(false,true)){
     //do some work
     BUSY.set(false);
  }else{
     //some other thread won, return now or retry later?
  }
}

したがって、ここでは常に1つのスレッドのみが使用さdoWorkれます。ブール値volatile booleanを設定したかどうか確信が持てないため、これをaで達成することはできません。Thread.currentThread()

于 2012-08-20T20:54:38.677 に答える
0

他の人が言ったように、変数をそれぞれ final / volatile にする必要があります。

あなたが説明したことから、次のようなことをする場所があるのではないかと思います。

if (!BUSY){
    BUSY = true;
}

2 つのスレッドがフラグをチェックし、両方ともフラグを false と見なして作業を開始する可能性があるため、コモンズ同期がない場合、これは壊れていることに注意してください。

並行性を処理するために既存の構造を調べることをお勧めします: http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/package-summary.html

特に、単一の許可を持つセマフォは、探しているものかもしれません。

于 2012-08-20T10:09:06.513 に答える