什么是多线程环境中的繁忙旋转?

Bra*_*avo 17 java multithreading

什么是多线程环境中的"忙碌旋转"?

它是如何有用的,它如何在多线程环境中的java中实现?

它在提高应用程序性能方面有何用处?

Sol*_*low 17

其他一些答案错过了忙碌等待的真正问题.

除非你在谈论一个关注节约电力的应用程序,否则燃烧CPU时间本身并不是一件坏事.当有一些其他线程或进程可以运行时,它才会变坏.当其中一个准备运行的线程是忙等待循环等待的线程时,它真的很糟糕.

这是真正的问题.在正常操作系统上运行的普通用户模式程序无法控制哪些线程在哪些处理器上运行,正常的操作系统无法区分繁忙等待的线程与正在工作的线程之间的区别,即使操作系统知道线程正忙着等待,它也无法知道线程在等待什么.

因此,忙碌的服务员完全有可能等待很多毫秒(几乎是永恒),等待事件,而唯一可以使事件发生的线程就在边线(即在运行队列中)等待轮到使用CPU了.

繁忙的等待通常用于可以严格控制哪些线程在哪些处理器上运行的系统中.当您知道导致它的线程实际上在不同的处理器上运行时,忙等待可能是等待事件的最有效方式.当您为操作系统本身编写代码时,或者当您编写在实时操作系统下运行的嵌入式实时应用程序时,通常会出现这种情况.


凯文沃尔特斯写了关于等待时间非常短的案例.可以允许在普通OS上运行的CPU绑定的普通程序在每个时间片中执行数百万条指令.因此,如果程序使用自旋锁来保护仅由几条指令组成的关键部分,那么任何线程在关键部分中都不会丢失其时间片.这意味着,如果线程A发现自旋锁锁定,则很可能该线程B,保持所述锁,实际上在不同的CPU上运行.这就是为什么当你知道它将在多处理器主机上运行时,在普通程序中使用自旋锁是可以的.

  • 当他们没有任何理由投票时,我真的很讨厌 (5认同)

SHA*_*SHA 10

忙等待或旋转是一种技术,其中进程重复检查以查看条件是否为真,而不是调用wait或sleep方法并释放CPU.

1.它主要用于多核处理器,其中条件将很快变为真,即以毫秒或微秒为单位

2.不释放CPU的优点是,所有缓存的数据和指令都不受影响,如果该线程暂停在一个核心并带回另一个线程,则可能会丢失


Jar*_*red 6

“忙旋转”在一个线程中不断循环,以查看另一个线程是否已完成某些工作。这是一个“坏主意”,因为它只是在等待而消耗资源。最繁忙的旋转甚至没有睡眠,而是尽可能快地旋转等待工作完成。直接通过工作完成通知等待线程并让它休眠直到那时浪费更少。

请注意,我称之为“坏主意”,但它在某些情况下用于低级代码以最小化延迟,但这在 Java 代码中很少(如果有的话)需要。

  • 假设您有一堆生产者线程将工作项推送到(同步)队列中,并且您有一个消费者线程从队列中弹出项目来为它们提供服务。当队列为空时,您的消费者线程不应轮询队列以获取工作项。相反,当添加新项目时,以某种方式向消费者发出信号。 (2认同)

roo*_*ler 6

忙碌的旋转是在不释放CPU的情况下等待事件的技术之一.通常这样做是为了避免丢失CPU缓存中的数据,如果线程暂停并在其他核心中恢复则会丢失.

因此,如果您正在处理低延迟系统,其中您的订单处理线程当前没有任何订单,而不是休眠或调用wait(),您只需循环然后再次检查队列中的新消息.如果你需要等待很短的时间,例如微秒或纳秒,这是唯一有益的.

LMAX Disrupter框架是一个高性能的线程间消息传递库,它有一个BusySpinWaitStrategy,它基于这个概念,并为等待屏障的EventProcessors使用繁忙的自旋循环.