防止工作缓慢接管线程池

时间:2019-01-31 11:50:18

标签: java multithreading concurrency threadpool

我有一个系统,当前每个作业都有它自己的Runnable类,并且我为每个作业预定义了固定数量的线程。

我的理解是这是错误的做法,因为:

  1. 您必须根据运行该进程的计算机调整线程数。
  2. 每个线程只能执行一种工作。

您是否同意? (当前解决方案是错误的)


因此,我想改用Java的ThreadPool之类的东西。我与一个说法相矛盾,该说法声称,这样做, 慢速作业将接管大部分线程池 ,而其他作业则没有任何余地。而在当前解决方案中,将固定数量的线程分配给了慢工,它不会损害其他线程。

(请注意,如果工作“缓慢”,您将无法先验)


系统如何既可以适应其使用的线程数,又可以不受最慢的工作的束缚?

2 个答案:

答案 0 :(得分:1)

您可以尝试获取完成工作所需的时间(使用手工制作的Timer类排序。然后,通过将该时间除以给定线程所花费的最长时间,可以标准化该值。最后,将这个数字乘以一个固定的数字,该数字取决于您每个作业每秒要运行的线程数。这将是该进程应使用的请求线程数。您可以根据需要进行调整。

编辑:您可以设置最小值和最大值,以调节作业有权获得的线程数。您也可以在另一个线程进入系统时从非常宽敞的作业中请求线程。

希望有帮助!

答案 1 :(得分:1)

更多的是业务问题。假设我是电信运营商。我禁止订户在未缴清会费时拨出电话。当他们付款时,我会清除一个标志,然后用户可以在一秒钟内拨打电话。但是我系统中还有许多其他活动,例如使用情况处理,计费,账单格式等。

现在让我们假设我有一个系统范围的通用线程池,并且开始了5万个订户的计费。我所有的线程现在都在处理运行时间相对较长的计费工作,并且正在建立一个庞大的队列。

一个贫穷的客户现在要付款,并且想拨打紧急电话。但是我的池中没有线程可以清除该标志。客户必须等待一个小时才能拨打电话。这是违反SLA的行为。

我应该做的是创建单独的线程池。如果呼叫解除阻塞作业不是很频繁且时间很短,我可以为其创建一个单独的池,核心大小可能为5。对于计费工作,我宁愿创建一个池,其核心大小为25,最大大小为30。

因此,无论如何我的系统限制也不会超出,因为即使在最坏的情况下,我也不会拥有超过30个线程。

这也将使其易于调试。如果每个池和每个池都有不同的线程名称模式,则系统会出现问题。我可以轻松地进行线程转储,了解帐单或付款方式是否是罪魁祸首。

因此,我认为现有设计基于一些业务用例,在提出解决方案之前您需要彻底了解这些用例。