Java中什么是快速、等待通知还是繁忙等待?
我知道使用忙等待不是一种好的编程实践,最好尽可能使用同步对象(waitnotify)。但我想知道,如果一个人准备牺牲cpu周期,那么繁忙等待会更快还是等待通知更快 我假设wait notify将涉及对同步对象的内在锁定,并且信号可能来自内核以唤醒线程,这使得这种方法比繁忙的等待慢得多,在繁忙的等待中,只需不断检查一个条件,直到它得到满足。只要满足这个条件(例如布尔值==true),线程就可以从繁忙等待中走出来。根据我的理解,我觉得忙碌的等待应该更快Java中什么是快速、等待通知还是繁忙等待?,java,multithreading,Java,Multithreading,我知道使用忙等待不是一种好的编程实践,最好尽可能使用同步对象(waitnotify)。但我想知道,如果一个人准备牺牲cpu周期,那么繁忙等待会更快还是等待通知更快 我假设wait notify将涉及对同步对象的内在锁定,并且信号可能来自内核以唤醒线程,这使得这种方法比繁忙的等待慢得多,在繁忙的等待中,只需不断检查一个条件,直到它得到满足。只要满足这个条件(例如布尔值==true),线程就可以从繁忙等待中走出来。根据我的理解,我觉得忙碌的等待应该更快 如果其他人能分享他们的想法并纠正我的论点错误,
如果其他人能分享他们的想法并纠正我的论点错误,我将不胜感激。人们愿意牺牲繁忙等待的CPU周期,因为这会更快。 忙等待是实时低延迟应用程序的一个示例 有一个叫做伦敦证券交易所的框架,其中一个锁定策略是忙碌等待,这就是他们如何使用它 为了实现超快,最好在通知锁时浪费cpu周期,而不是缩短时间 你对所有其他东西都是对的,如果你在disruptor上搜索一下,阅读他们的文章,你会得到更多的澄清。关于高性能和低延迟,有太多的话要说
一个好的博客是 实验表明,与等待并通知(无论如何,在我的硬件上)相比,如果您忙着等待,您将更快地看到该标志。(详情如下。)差异非常小,因此这只适用于非常罕见的应用程序。股票交易应用程序,例如,公司在追逐他们能获得的任何优势(试图将服务器定位在交易所附近,以便在交易所的网络馈送中获得微秒的改进等)。我还可以想象一些科学应用 在绝大多数应用程序中,这种差异实际上根本没有区别 但CPU的情况当然是,其中一个核心硬钉: 这对影响机箱上的其他进程和数据中心的功耗都是不利的 所以:只有在真正重要的情况下,才极不情愿地使用
数据(样本非常小,但代码如下):
WaitAndNotify.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));
}
}
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));
}
}
忙等待比正常等待快
视情况而定。有几种情况: 场景A 如果在“忙等待”中等待的是硬件操作(例如,从硬盘到内存读取扇区): 1) 硬件将执行此操作 2) 驱动程序将启动一个中断 3) 操作将停止实际进程(您的忙等待进程),保存中断将在其进程中覆盖的任何CPU寄存器的实际值 4) 中断将是处理,修改指示数据可用的任何标志(在磁盘读取的情况下) 5) 将恢复所有重写的寄存器 6) 您的流程将继续其流程。在下一次迭代中,它将调用循环的conthe条件。例如,如果忙等待为:
while( !fileReady() ){
...
}
fileReady()方法将是一个内部检查是否设置了具体标志(在4中修改的标志)的方法。
7) 因此,在下一次迭代中,循环将进入并执行操作
请记住,如果有另一个进程正在运行(操作系统进程、其他程序),它们会将您的进程置于进程尾部。此外,操作系统还可以决定,如果您的进程已经使用了它所能使用的所有CPU周期(它花费了它的数量),那么当它需要等待某个条件时,它的优先级将低于其他进入睡眠状态的进程(而不是使用忙等待方法)
结语。如果没有其他外部进程在同一个co中运行(不太可能),则速度会更快
while( !fileReady() ){
...
}
boolean exit = false;
while( exit==false ){
synchronize(var){
if(var = CONDITIONS_MEET)
exit=true;
}
}
//operations...