Java 如何创建等待布尔变量变为真的线程?
我有一个函数,一旦布尔变量为真,就需要调用它。我尝试在线程中使用while循环,但它不起作用。以下是我尝试过的:Java 如何创建等待布尔变量变为真的线程?,java,multithreading,Java,Multithreading,我有一个函数,一旦布尔变量为真,就需要调用它。我尝试在线程中使用while循环,但它不起作用。以下是我尝试过的: public class MyRunnable implements Runnable { public void run() { while (true) { if (conditions == true) { System.out.println("second"); break;
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
不要忙等待此类情况。使用阻塞式习惯用法。对于您的简单情况,您可以使用
新的倒计时锁存器(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;
}
}
为便于比较,带有倒计时闩锁的程序:
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();
}
}
要真正注意到差异,请在println(“first”)
之后添加线程。sleep(20000)
,并听到计算机风扇的声音差异,努力工作以消耗第一个程序正在浪费的能量。不要这样做。相反,您可以使用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
中查找更强大的方法,让线程在更有趣的条件下等待。所有这些都比在条件为真之前旋转要高效得多,而且由于Java内存模型的微妙之处,它们不太可能引入并发错误。这似乎是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();
}
}
}
整洁的但是,我不能在我的具体例子中使用它。我只发布了一个SSCCE。在我的代码中,我用另一种方法将条件设置为true。无论如何,谢谢。你可能永远也看不到这种情况下打印的“第二个”。主线程可以在run()
启动之前发送notify()
。然后,wait()
会无休止地等待,因为再也没有人通知它了。@Igor-它会不必要地使用CPU。浪费CPU是一个非常严重的问题,不仅仅是在性能方面。它浪费了更有形的东西:能源。即使你不关心电费或环境,每个人都关心他们设备的电池寿命。由于虚假的唤醒,等待必须在一个循环中完成,并且你必须首先获得状态
显示器上的锁。然后是notify
与notifyAll
的问题。。。最好忘记Java中存在这种机制。它履行了它的职责,是时候退休了。错误使用Runnable#Thread
并通过使用实数布尔变量while(canRun){
而不是无休止的while(true){