我知道使用 busy-wait 不是一个好的编程习惯,最好尽可能使用同步对象 (wait-notify)。但我想知道是否准备好牺牲 cpu 周期,那么忙等待会更快还是等待通知?
我假设 wait-notify 将涉及对同步对象的内部锁定,并且信号可能来自内核以唤醒线程,这使得这种方法比忙等待慢得多,后者可以连续检查条件直到满意为止。一旦满足此条件(例如 boolean 值 == true),线程就可以从忙等待中解脱出来。根据我的理解,我觉得忙等待应该更快。
如果我的论点有误,如果其他人能分享他们的想法并纠正我,我将不胜感激。
最佳答案
实验表明,如果您忙于等待,您会比等待并通知(无论如何在我的硬件上)更快地看到标志。 (详情如下。)区别是非常非常非常非常小,因此这只适用于非常罕见的应用程序。例如,股票交易应用程序,如果公司追求他们可以获得的任何优势(争先恐后地将他们的服务器定位在尽可能靠近交易所的位置,以便从交易所获得微秒级的网络反馈等),可能会认为这种差异是值得的。我也可以想象一些科学应用。
在绝大多数应用中,差异实际上没有任何差异。
但是发生在 CPU 上的当然是核心硬 Hook 之一:
就影响盒子上的其他进程和数据中心的功耗而言,这很糟糕。
因此:极不情愿地使用,仅在真正重要的情况下使用。
数据(非常小的样本,但代码如下):
Busy Wait: 10631 12350 15278 Wait and Notify: 87299 120964 107204 Delta: 76668 108614 91926
Times are in nanoseconds. Billionths of a second. The average delta above is 92403ns (0.092402667 milliseconds, 0.000092403 seconds).
BusyWait.java
:
public class BusyWait {
private static class Shared {
public long setAt;
public long seenAt;
public volatile boolean flag = false;
}
public static void main(String[] args) {
final Shared shared = new Shared();
Thread notifier = new Thread(new Runnable() {
public void run() {
System.out.println("Running");
try {
Thread.sleep(500);
System.out.println("Setting flag");
shared.setAt = System.nanoTime();
shared.flag = true;
}
catch (Exception e) {
}
}
});
notifier.start();
while (!shared.flag) {
}
shared.seenAt = System.nanoTime();
System.out.println("Delay between set and seen: " + (shared.seenAt - shared.setAt));
}
}
WaitAndNotify.java
:
public class WaitAndNotify {
private static class Shared {
public long setAt;
public long seenAt;
public boolean flag = false;
}
public static void main(String[] args) {
(new WaitAndNotify()).test();
}
private void test() {
final Shared shared = new Shared();
final WaitAndNotify instance = this;
Thread notifier = new Thread(new Runnable() {
public void run() {
System.out.println("Running");
try {
Thread.sleep(500);
System.out.println("Setting flag");
shared.setAt = System.nanoTime();
shared.flag = true;
synchronized (instance) {
instance.notify();
}
}
catch (Exception e) {
}
}
});
notifier.start();
while (!shared.flag) {
try {
synchronized (this) {
wait();
}
}
catch (InterruptedException ie) {
}
}
shared.seenAt = System.nanoTime();
System.out.println("Delay between set and seen: " + (shared.seenAt - shared.setAt));
}
}
关于java - 什么是快速、等待通知或忙等待?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24948791/