0

次のシナリオがあります。Java アプリケーション (Linux プラットフォーム上) で実行されている 2 つのスレッドがあり、スレッドは作成されるとすぐにスリープします。環境変数が設定されたときにスレッドを起動したい。

私は当初、変数を継続的にチェックするスレッドを作成するというアイデアを思いつきました。つまり、忙しい待機状態のように。しかし、CPUサイクルを消費するため、非効率的であることがわかります。そこで、環境変数が設定されている場合にスレッドを起動するというアイデアを思いつきました。

Javaでこれを実装する方法はありますか?前もって感謝します。

4

4 に答える 4

1

I wrote myself a Doze class for this.

It avoids using Thread.sleep completely by using a BlockingQueue internally. It is simple to use, as the main method shows. You just doze for a time and if anyone calls the Doze.wakeup() method you get woken up.

You will need to arrange for your Doze object to be available to the package that updates the property. On update it should call its wakeup().

/**
 * Use one of these to doze for a certain time.
 *
 * The dozing is fully interruptable.
 *
 * Another thread can stop the caller's doze with either a wakeup call or an abort call.
 *
 * These can be interpreted in any way you like but it is intended that a Wakeup is
 * interpreted as a normal awakening and should probably be treated in exactly the
 * same way as an Alarm. An Abort should probably be interpreted as a suggestion
 * to abandon the proces.
 */
public class Doze {
  // Special alarm messages.
  public enum Alarm {
    // Standard timeout.
    Alarm,
    // Just wake from your doze.
    Wakeup,
    // Abort the whole Doze process.
    Abort;
  }
  // My queue to wait on.
  private final ArrayBlockingQueue<Alarm> doze = new ArrayBlockingQueue<>(1);
  // How long to wait by default.
  private final long wait;

  public Doze(long wait) {
    this.wait = wait;
  }

  public Doze() {
    this(0);
  }

  public Alarm doze() throws InterruptedException {
    // Wait that long.
    return doze(wait);
  }

  public Alarm doze(long wait) throws InterruptedException {
    // Wait that long.
    Alarm poll = doze.poll(wait, TimeUnit.MILLISECONDS);
    // If we got nothing then it must be a normal wakeup.
    return poll == null ? Alarm.Alarm : poll;
  }

  public void wakeup() {
    // Just post a Wakeup.
    doze.add(Alarm.Wakeup);
  }

  public void abort() {
    // Signal the system to abort.
    doze.add(Alarm.Abort);
  }

  // Demo of use.
  public static void main(String[] args) throws InterruptedException {
    // Doze for 1 second.
    final Doze d = new Doze(1 * 1000);

    // Start a dozing thread.
    new Thread(new Runnable() {
      @Override
      public void run() {
        try {
          Alarm a = d.doze();
          // Wait forever until we are aborted.
          while (a != Alarm.Abort) {
            System.out.println("Doze returned " + a);
            a = d.doze();
          }
          System.out.println("Doze returned " + a);
        } catch (InterruptedException ex) {
          // Just exit on interrupt.
        }
      }
    }).start();

    // Wait for a few seconds.
    Thread.sleep(3000);

    // Wake it up.
    d.wakeup();

    // Wait for a few seconds.
    Thread.sleep(3000);

    // Abort it.
    d.abort();


  }
}
于 2013-09-13T14:32:36.107 に答える
0

シンプルなCountDownLatchを使用できます。

private final CountDownLatch latch = new CountDownLatch(1);

//in the threads that need to wait
latch.await(); //instead of sleep

//in the thread that sets the variable:
setVariable();
latch.countDown(); //wakes up the waiting threads
于 2013-09-13T17:35:24.340 に答える