如何创建一个等待布尔变量变为true的线程?

时间:2012-10-14 17:03:25

标签: java multithreading

我有一个函数需要在布尔变量为真时调用。我尝试在线程中使用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

3 个答案:

答案 0 :(得分: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")听取计算机风扇的声音差异,努力消耗第一个程序的能量浪费。

答案 1 :(得分: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();
    }
  }

}

答案 2 :(得分: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内存模型的细微之处,它们不太可能引入并发错误。