2

ブール変数が true になったら呼び出す必要がある関数があります。スレッドで while ループを使用しようとしましたが、機能しません。これが私が試したことです:

public class MyRunnable implements Runnable {

public void run() {
    while (true) {
         if (conditions == true) { 
             System.out.println("second");
             break;
         }
    }
}

public static void main(String args[]) {
    boolean condition = false;
    (new Thread(new MyRunnable())).start();
    System.out.println("first\n");
    // set conndition to true
    condition = true;

    }

}

結果は次のようになります。

first
second
4

3 に答える 3

14

忙しくしないでください-そのような状態を待ちます。ブロッキングイディオムを使用します。あなたの単純なケースでは、あなたはで逃げるでしょうnew CountDownLatch(1)。まず、これがあなたのコードですが、あなたが期待するようにコンパイルして実行するように修正されています:

public class MyRunnable implements Runnable {
  volatile boolean condition = false;

  public void run() {
    while (true) {
      if (condition) {
        System.out.println("second");
        break;
      }
    }
  }
  public static void main(String args[]) {
    final MyRunnable r = new MyRunnable();
    new Thread(r).start();
    System.out.println("first\n");
    r.condition = true;
  }
}

比較のために、CountDownLatch:を含むプログラム

public class MyRunnable implements Runnable {
  final CountDownLatch latch = new CountDownLatch(1);

  public void run() {
    try { latch.await(); } catch (InterruptedException e) {}
    System.out.println("second");
  }

  public static void main(String args[]) {
    final MyRunnable r = new MyRunnable();
    new Thread(r).start();
    System.out.println("first\n");
    r.latch.countDown();
  }
}

違いに本当に気付くには、Thread.sleep(20000)アフターprintln("first")を追加して、最初のプログラムが浪費しているエネルギーを放散するために一生懸命働いているコンピューターのファンの音の違いを聞いてください。

于 2012-10-14T17:08:17.650 に答える
3

これは、Java の待機通知構造の場所のようです。

public class MyRunnable implements Runnable {

  public run() {
    synchronized(this) {
      try {
        wait();
      } catch (InterruptedException e) {
      }
    }
    System.out.println("second");
  }

  public static void main(String args[]) {
    Runnable r = new MyRunnable();    
    Thread t = new Thread(r);
    t.start();
    System.out.println("first\n");
    synchronized (r) {
      r.notify();
    }
  }

}
于 2012-10-14T17:14:09.720 に答える
0

そのようにしないでください。Object代わりに、次のように組み込みのnotify()メソッドwait()を使用できます。

public class MyRunnable implements Runnable {

private final Object condition;

public MyRunnable(Object condition) {
    this.condition = condition;
}

public void run() {
    condition.wait();
    System.out.println("second");
}

public void go(String args[]) {
        Object condition = new Object();
        (new Thread(new MyRunnable(condition))).start();
        System.out.println("first\n");
        // set conndition to true
        condition.notify();
    }
}

より洗練された通知スキームが必要な場合はjava.util.concurrent、より興味深い条件でスレッドを待機させるより強力な方法を探すこともできます。これらはすべて、条件が真になるまでスピンするよりもはるかに CPU 効率が高く、Java のメモリ モデルの微妙な点により、同時実行のバグが発生する可能性が低くなります。

于 2012-10-14T17:12:26.493 に答える