while(true)和wait()或thread join()之间有什么区别?

3

我希望保持主线程的运行。我找到了三个选项,想知道哪个是最好的?它们之间有什么区别以及为什么?

它们中是否存在浪费资源的情况?

  1. while(true){}

  2. thread.join()

  3. CountDownLatch(1).await()

我尝试过它们,都能很好地工作。

while(true){}

thread.join()

CountDownLatch(1).await()

1
(2) 和 (3) 是糟糕的。(1) 更糟糕。 - Miha_x64
1
你是否有充分的理由使用 Kotlin?你真的在使用 Kotlin 吗?那么,协程可能会提供更好的方式来管理异步/并行。 - Jonas Wilms
@JonasWilms 谢谢你!!我会尝试查找协程。 - aguagu
3个回答

4

这里:

while(true){}

“热”等待是什么意思呢?它意味着你的CPU在100%运转,却没有任何作用。也许,如果你很幸运,JVM会检测到这一点,并能够避免像这样消耗CPU周期。
而对于join(),我们可以找到以下内容:
当我们在线程上调用join()方法时,调用线程进入等待状态。它将保持等待状态,直到引用线程终止为止。
(来自此tutorial
因此,join()听起来更健康。await()应该以类似的方式工作。
这两种方法的缺点是它们对线程中断做出反应,所以将它们放入“while true”循环可能是一个好主意。

我认为join()或wait()方法的代码像while(true)循环一样编码...尝试找到代码,但我找不到... - aguagu
2
@aguagu 不是的。一个等待线程和一个在循环中使用“nop”指令占用CPU的线程不是同一回事。 - GhostCat

3

它们之间是否存在浪费资源的情况?

无限循环肯定会浪费资源,因为它没有原因地迭代,并消耗计算时间和能量。

另外两个不应该浪费资源,因为它们在被阻塞时允许操作系统同时执行其他线程。


3

它们本身都不足以胜任。

while(true){}

无尽的忙碌循环在处理器上永远旋转,产生热量并消耗电力。它无法干净地停止。

thread.join()

等待另一个线程完成。这与其他线程不同,因为它实际上可以完成,而不是永远运行下去。但是如果应用程序只由另一个线程运行直到完成,那么为什么不在主线程中运行代码,而要创建另一个线程并等待它完成呢?

CountDownLatch(1).await()

创建一个监视器并永久等待它。这与以下内容几乎相同:
Object o = new Object();
synchronized (o) {
    o.wait();
}

再次强调,没有干净利落的停止程序的方法。

最后一个方法——CountDownLatch——是与之相近的一种可行的方法。不要立即丢弃与门闩有关的引用,而是将其传递给控制执行的代码,以便它可以告诉主线程停止的时间。但是,将CountDownLatch本身作为退出条件的信号会产生混淆。退出信号是布尔类型,因此Semaphore更合适。

Semaphore exitPermission = new Semaphore(0);
// Pass exit permission around.
exitPermission.acquire();

但这仍然允许接收者干扰状态(通过尝试获取它并干扰调度),因此Semaphore应该被隐藏在一个只允许其他人释放它的接口后面。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接