【问题标题】:Thread pool that also uses the calling thread?也使用调用线程的线程池?
【发布时间】:2018-06-28 04:08:03
【问题描述】:

是否有任何线程池实现也允许使用调用线程执行?

一些背景知识 - 我有一项服务需要调用许多相关服务(并对它们的结果进行一些处理)。我的服务是大规模并行的,可能使用多达 1000 个线程来处理并发请求(真的,我不是在开玩笑)。

当然,并行处理的一个常见模式是共享后台线程池,用于将工作从主线程中分出。它还有一个基本的耗尽问题,如果 1000 个服务线程中的每一个都提交一个长时间运行的请求,那么很容易完全耗尽池的所有容量。

另一个经典的解决方案是为每个服务线程使用一个私有线程池。这不是很吸引人,因为我无法使这些私人游泳池足够大。

所以我的想法是使用一种特殊类型的线程池执行器,它在调用线程中运行任务,如果它有空闲容量,则机会主义地使用后台线程池来运行任务。这样我可以保证调用线程在任何情况下都会取得一些进展,即使后台池已经耗尽。

有人知道这样的线程池实现吗?

【问题讨论】:

  • 创建一个有界队列的ThreadPoolExecutor 和一个CallerRunsPolicy
  • 这行得通。在正常处理期间在调用者线程中运行任务仍然很好,但我可以忍受它。

标签: java multithreading architecture threadpool


【解决方案1】:

虽然问题不是很清楚,但听起来线程大部分都在阻塞等待来自其他服务的响应。这不是对这些线程非常有效的使用。大量线程经常导致调度器运行inefficiently

或者,您可以考虑使用带有完成处理程序的异步套接字。这避免了阻塞 i/o,并在代码中调用处理程序,您可以在其中响应通道中发生的 i/o 事件。

这最终意味着您可以大量减少应用程序中的线程数量,并且应该提高性能。

【讨论】:

  • 是的,线程大部分时间都花在等待网络回复上,并且大多数耗尽情况发生在依赖服务之一变得太慢时。不幸的是,我用于这些服务的 SDK 都是同步的(毕竟这是 Java),我不能花很多时间将它们重写为异步事件循环。
  • 听起来可能值得付出努力,但如果不是立即考虑,那么将来需要考虑什么?... 恕我直言,每个套接字线程并不是最好的方法。
【解决方案2】:

另一种方法是在调用线程和线程池之间放置一个任务队列。每个请求都放在队列中,worker 依次处理队列中的任务。当任务完成时,通知将发送回调用线程。

使用这种机制,您始终可以确保任务最终得到处理。

【讨论】:

    猜你喜欢
    • 2011-11-23
    • 1970-01-01
    • 1970-01-01
    • 2018-10-02
    • 2016-09-01
    • 2023-03-12
    • 2011-12-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多