17

スレッドを一時停止する方法を探しています。

ブールフラグ(「一時停止」と呼ばれる)を効果的に使用し、チェックをwhileループ(一時停止)でラップすることから始めました。

whileループ内にはThread.wait()、実行をブロックするためのがあります。

私はAtomicBooleanを見てきました。これは、ブロックされないことを除けば、トリックを実行しているようです。

ブロックメソッドを持つAtomicBooleanの代替バージョンまたは拡張バージョンはありますか?

つまりAtomicBoolean.getFalse()AtomoicBoolean.get(false)

それらにはブロッキングキューがあるため、ブロッキング値です。

現在の設定は次のとおりです。

while (paused.get()) {
        synchronized (paused) {
            try {

                paused.wait();
            } catch (Exception e) {
            }

            paused.notify();
        }
    }

public void pause() {
    if (paused.compareAndSet(false, true)) {
        synchronized (paused) {
            paused.notify();
        }
    }

}


public void resume() {
    if (paused.compareAndSet(true, false)) {
        synchronized (paused) {
            paused.notify();
        }
    } 
}
4

5 に答える 5

15

CountDownLatch1のaを使用します。

CountDownLatch conditionLatch = new CountDownLatch(1);

ある条件が真になるのを待ちたい場所で:

conditionLatch.await();

条件をtrueに設定する場所:

conditionLatch.countDown();
于 2018-03-27T23:11:59.947 に答える
14
    AtomicBoolean lock = new AtomicBoolean(false);
    if(lock.compareAndSet(false, true)){
        try {
            //do something
        } catch(Exception e){
            //error handling
        } finally {
            lock.set(false);
        }
    }

まず、アトミック操作(テストアンドセットなど)を使用しない限りAtomicBoolean、通常のブール値(可変の場合)と同じくらい役に立たない。ここでは、を使用しcompareAndSetているので、フラグが下がっている場合にのみクリティカルセクションに入ります。常に最後にロックを解除することを忘れないでください。

フラグを使用してスレッドを一時停止するには、アクティブな待機(「一時停止しましたか?」を尋ねるスレッド本体のループ)を行わないでください。これは効率的な方法ではありません。待機通知スキームを使用します。スレッドに実行する作業がなくなると、スレッドはwaitいくつかのオブジェクトを呼び出します。次に、再起動するために、他のスレッドがnotify同じオブジェクトを呼び出します。

すぐに一時停止したい場合(フラグが設定されている場合のスキップ実行に関して)、コードを可能な限り多くのステップに分割し、各ステップをテストでラップして、一時停止した場合に最終的に待機することができます。

public void run(){
    while(true){
        if(!paused){
            //do something
        }

        if(!paused){
            //do something
        }

        if(!paused){
            //do something
        }

        if(!paused){
            //do something
        }

        if(paused){
            //wait on some object
        }
    }       
}   

コードによっては、ステップがネストされている場合や、複数のステップを含む分割できない実行単位が含まれている場合があります。

于 2011-11-21T16:02:09.360 に答える
3

私はあなたの質問を理解したかどうかわかりません;とにかくあなたはクラスjava.util.concurrent.Semaphoreを見ましたか?permit = 1のセマフォは、目的の動作を提供するはずです。エミュレートできます。

paused = true;

との指導

semaphore.tryAcquire();

また

semaphore.acquire();

発信者をロックしたい場合。スレッドを解放することができます

semaphore.release();

于 2011-11-21T14:41:55.043 に答える
1

ロックを使用できます。

あなたのスレッドで。

while(!Thread.interrupted()) {
  lock.lock();
  try {
      // do something.
  } finally {
      lock.unlock();
  }
}

// to pause
lock.lock();

// to unpause
lock.unlock(); // has to be the same thread which locked.

または、ウェイクアップするためにスレッドが必要な速さによっては、忙しい睡眠をとることができます。

while(atomicBoolean.get()) Thread.sleep(100); // or yield();
于 2011-11-21T14:13:51.143 に答える
0

で実行できる特定の時間を待っいるか、準備ができるのを待っているオブジェクトを呼び出す必要があることを示す何かThread.sleep()を待つ必要があります。wait()

スレッドに作業を続行するように手動で指示できる必要がある場合はwhile(true)、呼び出しを含むループを作成Thread.sleep()し、ブール値をチェックして、break適切に設定されているかどうかを確認します。でも、そうする理由は思いつかない。

于 2011-11-21T14:14:03.170 に答える