在 Java 中更改线程的优先级需要多长时间?
How long does it take to change a thread's priority in Java?
我找不到任何关于更改线程优先级是否是一项耗时的操作的声明。我想经常这样做,但如果每次切换都会带来显着的时间损失,那可能不值得这么麻烦。
What I can't find is any statement on whether changing a thread's priority is a costly operation, time-wise. I would like to do it frequently, but if each switch carries a significant time penalty it is probably not worth the trouble.
这里的任何答案都将非常 OS 依赖。我怀疑大多数 Unix 变体的答案是否定的,它并不昂贵。它可能需要某种数据同步,否则它只是在线程的管理信息上设置一个值。我怀疑没有像评论中讨论的那样重新安排线程。
也就是说,在不了解您的特定用例的更多信息的情况下,我怀疑这样做是否值得。正如我在下面列出的答案中所说,关于线程优先级唯一会有所不同的是,如果所有线程都完全 CPU 绑定并且您希望一个或另一个任务获得更多周期。
此外,线程优先级是非常非线性的,对它们进行小的更改可能几乎没有影响,因此设置线程优先级所产生的任何开销都将压倒通过更改它们获得的任何好处。
在这里查看我的回答:
Guide for working with Linux thread priorities and scheduling policies?
此外,请查看这篇关于 Java thread priorities 的文章以及在 Linux 下对它们进行的一些真实测试。引用:
As can be seen, thread priorities 1-8 end up with a practically equal share of the CPU, whilst priorities 9 and 10 get a vastly greater share (though with essentially no difference between 9 and 10). The version tested was Java 6 Update 10.
在 Windows 的情况下,调用 SetThreadPriority 以将就绪线程的优先级更改为 运行 是一个系统调用,会将线程从其当前优先级就绪队列移动到不同优先级的就绪队列,这比在线程对象中设置一些值更昂贵。
如果 SetThreadPriority 用于增加线程的优先级,并且如果这导致当前优先级较高的线程抢占优先级较低的线程,则抢占发生在调用时,而不是下一个时间片。
这里提到就绪队列:
https://msdn.microsoft.com/en-us/library/windows/desktop/ms682105(v=vs.85).aspx
此处提到了与优先级更改相关的上下文切换:"The following events might require thread dispatching ... A thread’s priority changes, either because of a system service call or because Windows itself changes the priority value." 和 "Preemption ... a lower-priority thread is preempted when a higher-priority thread becomes ready to run. This situation might occur for a couple of reasons: A higher-priority thread’s wait completes ... A thread priority is increased or decreased." 还提到了就绪队列:"Windows multiprocessor systems have per-processor dispatcher ready queues"
https://www.microsoftpressstore.com/articles/article.aspx?p=2233328&seqNum=7
我在 MSDN 论坛上问过这个问题。第四个 post 与我在本线程中的第一个和第三个 post 中提到的顺序一致:
在 Linux 的当前版本中,运行 按优先级索引的队列已被红黑树取代。更改线程的优先级将涉及在红黑树中删除和重新插入线程对象。如果线程对象移动到红黑树的"left"足够多,就会发生抢占。
https://www.ibm.com/developerworks/library/l-completely-fair-scheduler
回应关于 "examines a full-speed stream of incoming Bluetooth data packets" 应用程序的评论,接收线程应该具有最高优先级,希望它的大部分时间不会 运行ning 用于等待数据包的接收。高优先级的数据包将排队等候由优先级比接收线程低的另一个线程处理。如果需要,多个处理线程可以利用多个内核。
我找不到任何关于更改线程优先级是否是一项耗时的操作的声明。我想经常这样做,但如果每次切换都会带来显着的时间损失,那可能不值得这么麻烦。
What I can't find is any statement on whether changing a thread's priority is a costly operation, time-wise. I would like to do it frequently, but if each switch carries a significant time penalty it is probably not worth the trouble.
这里的任何答案都将非常 OS 依赖。我怀疑大多数 Unix 变体的答案是否定的,它并不昂贵。它可能需要某种数据同步,否则它只是在线程的管理信息上设置一个值。我怀疑没有像评论中讨论的那样重新安排线程。
也就是说,在不了解您的特定用例的更多信息的情况下,我怀疑这样做是否值得。正如我在下面列出的答案中所说,关于线程优先级唯一会有所不同的是,如果所有线程都完全 CPU 绑定并且您希望一个或另一个任务获得更多周期。
此外,线程优先级是非常非线性的,对它们进行小的更改可能几乎没有影响,因此设置线程优先级所产生的任何开销都将压倒通过更改它们获得的任何好处。
在这里查看我的回答: Guide for working with Linux thread priorities and scheduling policies?
此外,请查看这篇关于 Java thread priorities 的文章以及在 Linux 下对它们进行的一些真实测试。引用:
As can be seen, thread priorities 1-8 end up with a practically equal share of the CPU, whilst priorities 9 and 10 get a vastly greater share (though with essentially no difference between 9 and 10). The version tested was Java 6 Update 10.
在 Windows 的情况下,调用 SetThreadPriority 以将就绪线程的优先级更改为 运行 是一个系统调用,会将线程从其当前优先级就绪队列移动到不同优先级的就绪队列,这比在线程对象中设置一些值更昂贵。
如果 SetThreadPriority 用于增加线程的优先级,并且如果这导致当前优先级较高的线程抢占优先级较低的线程,则抢占发生在调用时,而不是下一个时间片。
这里提到就绪队列:
https://msdn.microsoft.com/en-us/library/windows/desktop/ms682105(v=vs.85).aspx
此处提到了与优先级更改相关的上下文切换:"The following events might require thread dispatching ... A thread’s priority changes, either because of a system service call or because Windows itself changes the priority value." 和 "Preemption ... a lower-priority thread is preempted when a higher-priority thread becomes ready to run. This situation might occur for a couple of reasons: A higher-priority thread’s wait completes ... A thread priority is increased or decreased." 还提到了就绪队列:"Windows multiprocessor systems have per-processor dispatcher ready queues"
https://www.microsoftpressstore.com/articles/article.aspx?p=2233328&seqNum=7
我在 MSDN 论坛上问过这个问题。第四个 post 与我在本线程中的第一个和第三个 post 中提到的顺序一致:
在 Linux 的当前版本中,运行 按优先级索引的队列已被红黑树取代。更改线程的优先级将涉及在红黑树中删除和重新插入线程对象。如果线程对象移动到红黑树的"left"足够多,就会发生抢占。
https://www.ibm.com/developerworks/library/l-completely-fair-scheduler
回应关于 "examines a full-speed stream of incoming Bluetooth data packets" 应用程序的评论,接收线程应该具有最高优先级,希望它的大部分时间不会 运行ning 用于等待数据包的接收。高优先级的数据包将排队等候由优先级比接收线程低的另一个线程处理。如果需要,多个处理线程可以利用多个内核。