当前位置: 首页 > 知识库问答 >
问题:

工作/任务窃取线程池执行器

梅安平
2023-03-14

在我的项目中,我正在构建一个Java的执行框架,它接收来自客户端的工作请求。工作(大小不同)被分解为一组任务,然后排队等待处理。有单独的队列来处理每种类型的任务,每个队列都与一个ThreadPool相关联。ThreadPools的配置方式使引擎的整体性能达到最佳。

这种设计有助于我们有效地平衡请求的负载,大型请求不会占用系统资源。然而,当一些队列为空并且它们各自的线程池闲置时,该解决方案有时会变得无效。

为了更好地实现这一点,我考虑实现一种工作/任务窃取技术,以便重载队列可以从其他线程池获得帮助。然而,这可能需要实现我自己的执行器,因为Java不允许多个队列与线程池相关联,也不支持工作窃取概念。

阅读有关Fork/Join的内容,但这似乎不符合我的需求。任何构建此解决方案的建议或替代方法都会非常有帮助。

谢谢Andy

共有3个答案

施德元
2023-03-14

您可以实现一个定制的BlockingQueue实现(我认为您主要需要实现< code>offer()和< code>take()方法),它由一个“主”队列和0个或更多的辅助队列支持。如果非空,take将总是从主后备队列中提取,否则它可以从辅助队列中提取。

事实上,使用一个池可能更好,在这个池中,所有的工作人员都可以访问所有的队列,但是“更喜欢”某个特定的队列。你可以通过给不同的员工分配不同的优先级来得出你的最佳工作比例。在满负荷的系统中,您的员工应该以最佳的比率工作。在负载不足的系统中,您的工作人员应该能够帮助处理其他队列。

柴彬
2023-03-14

你有没有考虑过ForkJoinpool?fork-连接框架是以一种很好的模块化方式实现的,因此您可以只使用偷工作的线程池

端木高卓
2023-03-14

Java 8在< code>Executors类中有工厂和实用方法:< code > Executors . newworkstealingpool

我相信,这正是您想要的工作窃取线程池的实现。

 类似资料:
  • 我试图理解工作窃取对递归任务的影响:工作窃取的一个优点是,当前的工作线程/线程可能会执行自己的生成任务;增加数据局部性。但是,在常见情况下,当工作线程加入其生成的任务时会发生什么?例如: 我认为这里当前线程会被阻塞,因此无法从自己的队列中获取工作,因此另一个工作人员将不得不窃取这些工作。这将否认工作窃取的局部优势。然而,根据维基百科(https://en.wikipedia.org/wiki/Wo

  • 我试图理解fork-join的窃取部分。fork-join池具有具有自己Deque的工作线程。如果工作线程自身的deque为空,则该线程从另一个工作线程中窃取。 线程如何访问其他线程的状态? 当所有者线程和窃取者线程尝试访问取消排队中的同一项目时,它不会产生同步问题吗?

  • 我正在使用线程池执行器更改遗留设计。详情如下:- 遗留:-对于遗留设计,在应用程序启动时创建600个线程。和放置在各种池中,然后在需要时提取这些池,并将任务分配给相应的线程。 新:-在新设计中,我将线程池替换为执行器服务 我观察到的是,对于Executor,在启动时不会创建线程。它们是在从客户端激发请求时创建的。因此,与前一个线程相比,在内存中创建的线程要少得多。 但我的问题是,这样做是否正确,因

  • 目前,我正在使用一个围绕脚本共享的执行器服务的全局实例。我的想法是调用并将任务添加到池中,以便线程进行工作,当所有线程都完成时,然后写入输出文件以获取结果。 下面是一个小视图:主线程调用t0、t1、t2、t3,t0调用t4、t5。其他线程也可以调用其他线程。 问题是shutdown()和awaitTermination()在t0、t1、t2、t3时被调用并完成,而没有等待t4和t5。因此,当t4和

  • 问题内容: 在http://marcio.io/2015/07/handling-1-million-requests-per-minute-with- golang/ 提供的示例中,很多地方都引用了该示例。 分派服务完许多工作后,工人池(chan chan工作)会不会耗尽?因为从信道和信道工作拉出第一类型后没有被补充被调用的第一次?还是我想念/误读了什么?如何为WorkerPool补充可用的工作

  • 本文向大家介绍Spring Boot中配置定时任务、线程池与多线程池执行的方法,包括了Spring Boot中配置定时任务、线程池与多线程池执行的方法的使用技巧和注意事项,需要的朋友参考一下 配置基础的定时任务 最基本的配置方法,而且这样配置定时任务是单线程串行执行的,也就是说每次只能有一个定时任务可以执行,可以试着声明两个方法,在方法内写一个死循环,会发现一直卡在一个任务上不动,另一个也没有执行