Sac*_*hin 5 java multithreading
我知道使用busy-wait不是一个好的编程习惯,最好尽可能使用同步对象(wait-notify).但是我想知道一个人是否准备好牺牲cpu周期,然后忙着等待更快或等待通知?
我假设wait-notify将涉及对同步对象的内部锁定,并且信号可能来自内核以唤醒线程,使得这种方法比忙碌等待慢得多,其中人们可以直接检查条件直到它是满意.只要满足此条件(例如,布尔值== true),线程就可以从繁忙的等待中退出.根据我的理解,我感到很忙 - 等待应该更快.
如果我的论点是错误的,如果其他人能分享他们的想法并纠正我,我将不胜感激.
T.J*_*der 10
实验表明,如果你等待并等待并通知(在我的硬件上,无论如何),你会更快地看到旗帜.(详情如下.)差异非常非常非常小,所以这只适用于非常罕见的应用程序.例如,股票交易应用程序,公司可以获得他们可以获得的任何优势(争取尽可能在交易所附近找到他们的服务器,以便从交易所获得微网改进等)可能会认为差异是值得的.我也可以想象一些科学应用.
在绝大多数应用程序中,差异实际上没有任何区别.
但是,CPU发生的事情当然是其中一个核心硬件:

在影响盒子上的其他进程和数据中心的功耗方面,这是不好的.
所以:只有在真正重要的情况下才极度不情愿地使用.
数据(非常小的样本,但代码如下):
Busy Wait: 10631 12350 15278 Wait and Notify: 87299 120964 107204 Delta: 76668 108614 91926
时间是纳秒.十亿分之一秒.上面的平均增量为92403ns(0.092402667毫秒,0.000092403秒).
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));
}
}
Run Code Online (Sandbox Code Playgroud)
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));
}
}
Run Code Online (Sandbox Code Playgroud)
人们准备好在繁忙等待时牺牲 CPU 周期,因为它更快。繁忙等待是实时低延迟应用程序的示例。
有一个名为lmax Disruptor 的框架,是为伦敦证券交易所构建的,锁定策略之一是忙等待,这就是他们使用它的方式。
为了达到超快的速度,最好在通知锁时浪费 CPU 周期,而不是浪费时间。
你对所有其他事情都是正确的,如果你用谷歌搜索一下disruptor并阅读他们的论文,你会得到更多的澄清。关于高性能和低延迟,有太多话可说。
Mechanical Sympathy是一个值得一看的好博客。
| 归档时间: |
|
| 查看次数: |
6651 次 |
| 最近记录: |