thread class 的 onSpinWait() 方法 - Java 9
在学习Java 9功能时,我遇到了一种新的类方法,称为onSpinWait
。根据javadocs,此方法用于此:Thread
指示调用方暂时无法前进,直到其他活动发生一个或多个操作。
有人能帮助我理解这种方法,给出一个现实生活中的例子或场景吗?
在学习Java 9功能时,我遇到了一种新的类方法,称为onSpinWait
。根据javadocs,此方法用于此:Thread
指示调用方暂时无法前进,直到其他活动发生一个或多个操作。
有人能帮助我理解这种方法,给出一个现实生活中的例子或场景吗?
它与x86操作码相同(并且可能编译为),相当于Win32宏,GCC和C#方法PAUSE
YieldProcessor
__mm_pause()
Thread.SpinWait
这是一种非常弱化的屈服形式:它告诉你的CPU你处于一个循环中,可能会消耗许多CPU周期等待某些事情发生(忙碌等待)。
这样,CPU可以将更多资源分配给其他线程,而无需实际加载操作系统调度程序并使准备运行的线程排出队列(这可能很昂贵)。
它的常见用法是自旋锁定,当您知道共享内存上的争用非常不频繁或完成得非常快时,自旋锁可能比普通锁更好。
此类伪代码可能如下所示:
int state = 0; //1 - locked, 0 - unlocked
routine lock:
while state.cas(new_value=1, wanted_value=0) == false //if state is 0 (unlocked), store 1 (locked) and return true, otherwise just return false.
yield
routine unlock:
atomic_store(state,0)
yield
可以使用 来实现,提示在尝试锁定锁的同时,CPU 可以向其他线程提供更多资源。Thread.onSpinWait()
在实现无锁算法时,这种良率技术非常普遍和流行,因为它们中的大多数都依赖于忙等待(几乎总是作为原子比较和交换循环实现)。这具有您可以想象的所有实际用途。
纯系统提示!
阅读这篇文章,我引用:
目标
定义一个 API,该 API 将允许 Java 代码向运行时系统提示它位于旋转循环中。API 将是一个纯粹的提示,并且不带有语义行为要求(例如,no-op 是有效的实现)。允许 JVM 从特定于自旋循环的行为中受益,这些行为在某些硬件平台上可能很有用。在 JDK 中提供无操作实现和内部实现,并在至少一个主要硬件平台上展示执行优势。
很多时候,线程必须挂起,直到超出其范围的内容发生更改。一个(曾经)常见的做法是有一个线程等待另一个线程唤醒它们的模式。wait() notify()
这有很大的限制,即另一个线程必须知道可能存在等待线程并应通知。如果其他线程的工作超出您的控制范围,则无法收到通知。
唯一的办法就是旋转等待。假设您有一个程序来检查新电子邮件并通知用户:
while(true) {
while(!newEmailArrived()) {
}
makeNotification();
}
这段代码将每秒执行数百万次;一遍又一遍地旋转,使用宝贵的电力和CPU功率。执行此操作的常见方法是在每次迭代时等待几秒钟。
while(true) {
while(!newEmailArrived()) {
try {
Thread.sleep(5000);
} catch(InterruptedException e) {
}
}
makeNotification();
}
这做得很好。但是,在您必须立即工作的情况下,睡眠可能不是问题。
Java 9试图通过引入这个新方法来解决这个问题:
while(true) {
while(!newEmailArrived()) {
Thread.onSpinWait();
}
makeNotification();
}
这将与没有方法调用完全相同,但系统可以自由地降低进程优先级;当其他更重要的事情需要资源时,减慢循环或减少该环路的电力。