关于在线程之间切换上下文(与 wait/notify 同步)并将任务(Callable/Runnable)重新提交给 Executor 服务,哪个对性能更好?据我所知,切换上下文需要保存/重新加载线程数据,但是如果我将任务重新提交给执行器服务,JVM 需要为提交的任务重新分配堆栈,所以我认为它与切换上下文具有相同的成本?
我设计了一个任务队列,供工作线程将任务放入其中,并设计一个监视器线程来获取队列中的任务,将任务提交到线程池(执行器服务)。但我考虑一下监视器线程什么时候工作? 选项1:对监视器线程和工作线程使用线程“等待”,将任务放入队列后通知监视器线程。 选项 2:使用监视器线程的调度程序执行器服务来检查队列。 -> 哪个选项更好(对于速度、性能)以及选项 2:检查队列的频率是最好的?
非常感谢您的帮助
最佳答案
执行器通常由线程池支持。所以堆栈已经分配了。此外,仅当相同 CPU 核心必须执行两个线程时才会发生上下文切换。现代 CPU 具有多个核心,因此不会涉及上下文切换。
话虽如此,将工作转移到另一个线程肯定会产生一些开销。因此,任务应该足够粗粒度,并且主线程应该同时执行其他工作,以使池受益。
如果队列本身是同步的,则不需要监视器线程。看看
ArrayBlockingQueue
例如;生产者可以调用 put() 方法(当队列中没有可用空间时会阻塞),消费者(池中的线程)调用 take() 方法会阻塞当没有工作可做时。就是这样ThreadPoolExecutor
已实现(准确地说,它实际上调用了offer()
,因此默认情况下不会在生产者端阻塞)。
关于Java多线程切换上下文VS提交新任务以及监控队列的解决方案,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61054449/