Java多线程切换上下文VS提交新任务以及监控队列的解决方案

标签 java multithreading performance

  • 关于在线程之间切换上下文(与 wait/notify 同步)并将任务(Callable/Runnable)重新提交给 Executor 服务,哪个对性能更好?据我所知,切换上下文需要保存/重新加载线程数据,但是如果我将任务重新提交给执行器服务,JVM 需要为提交的任务重新分配堆栈,所以我认为它与切换上下文具有相同的成本?

  • 我设计了一个任务队列,供工作线程将任务放入其中,并设计一个监视器线程来获取队列中的任务,将任务提交到线程池(执行器服务)。但我考虑一下监视器线程什么时候工作? 选项1:对监视器线程和工作线程使用线程“等待”,将任务放入队列后通知监视器线程。 选项 2:使用监视器线程的调度程序执行器服务来检查队列。 -> 哪个选项更好(对于速度、性能)以及选项 2:检查队列的频率是最好的?

非常感谢您的帮助

最佳答案

  1. 执行器通常由线程池支持。所以堆栈已经分配了。此外,仅当相同 CPU 核心必须执行两个线程时才会发生上下文切换。现代 CPU 具有多个核心,因此不会涉及上下文切换。

    话虽如此,将工作转移到另一个线程肯定会产生一些开销。因此,任务应该足够粗粒度,并且主线程应该同时执行其他工作,以使池受益。

  2. 如果队列本身是同步的,则不需要监视器线程。看看ArrayBlockingQueue例如;生产者可以调用 put() 方法(当队列中没有可用空间时会阻塞),消费者(池中的线程)调用 take() 方法会阻塞当没有工作可做时。就是这样ThreadPoolExecutor已实现(准确地说,它实际上调用了 offer(),因此默认情况下不会在生产者端阻塞)。

关于Java多线程切换上下文VS提交新任务以及监控队列的解决方案,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61054449/

相关文章:

c++ std::thread 构造函数用法

javascript - 点击事件后显示隐藏的 div 在 phonegap 中很慢

c# - 返回结果还是先放到变量中?

java - 对同一选择器的 socketChannel 的注册调用会引发异常

java - 无法绘制正确的线性图,其中 X 是日期时间戳

Javafx 应用程序在执行线程等待和通知时挂起

c++ - std::wstring_convert 线程的成员函数是否安全?

c# - 使用多个有限数量的线程处理项目列表

java - Typical Requests/Second a "server"能处理吗?

java - Spring框架的XmlBeanDefinitionStoreException : The prefix "beans" for element "beans:bean" is not bound