1

我正在尝试调整执行以下操作的线程:

只有 1 个线程的线程池[CorePoolSize =0, maxPoolSize = 1]

使用的队列是ArrayBlockingQueue

Quesize = 20

背景:
线程尝试读取请求并对其执行操作。

但是,最终请求增加得如此之多,以至于线程总是很忙并消耗 1 个 CPU,这使其成为资源占用。

我想要做的是,而是每隔一段时间对请求进行采样并处理它们。可以安全地忽略其他请求。

我要做的就是在“操作”函数中设置一个睡眠,这样对于每个任务,线程都会睡眠一段时间并释放 CPU。

问题:
但是,我想知道是否有一种方法可以使用一个队列,该队列基本上本身会在读取下一个元素之前休眠一段时间。这将是理想的,因为在执行过程中休眠任务并保持执行不完整对我来说听起来并不是最好的。

如果您对任务还有其他建议,请告诉我

谢谢。

编辑:我在这里添加了一个后续问题, 将 maxpool 大小更正为 1 [匆忙编写] .. 感谢 tim 指出。

4

4 回答 4

1

线程消耗 100% CPU 的原因是它被分配了比它可以处理的更多的工作。在任务之间添加延迟并不能解决这个问题。这只会让事情变得更糟。

相反,您应该查看为什么您的任务会消耗如此多的 CPU,例如使用分析器并更改它们以减少 CPU 消耗,直到您发现您的线程可以跟上并且不再消耗 100% 的 cpu。

于 2010-10-07T19:49:43.857 回答
1

不,当它在池中时,你不能让线程休眠。如果队列中有任务,它将被执行。

在队列任务中暂停是强制线程空闲的唯一方法,而不管队列任务。现在,“睡眠”不必与“工作”在同一个任务中——您可以在每个实际任务之后排队一个单独的休息任务,这可能会使实现更简洁。更重要的是,如果工作是一个Callable返回结果的工作,分成两个任务可以让你尽快得到结果。

作为一种改进,您可以将执行“节流”到指定的速率,而不是在每个任务之间按固定间隔休眠。这将允许您避免在任务之间不必要地等待,同时避免在指定的时间间隔内执行过多的任务。您可以阅读我的另一个答案,了解使用DelayQueue.

于 2010-10-05T00:11:47.473 回答
1

您可以继承 ThreadPool 并覆盖beforeExecute以休眠一段时间:

@Overrides
protected void beforeExecute(Thread t,
                         Runnable r){
    try{
       Thread.sleep( millis);  // will sleep the correct thread, see JavaDoc
    }
    catch (InterruptedException e){}

  }

但是请参阅 AngerClown 关于人为减慢队列的评论可能不是一个好主意。

于 2010-10-05T00:18:58.777 回答
1

这可能对您不起作用,但您可以尝试将执行程序的线程优先级设置为低。

本质上,使用自定义ThreadFactory创建ThreadPoolExecutor。让该方法返回优先级为Thread.MIN_PRIORITY的线程。这将导致您使用的执行器服务仅在有可用核心运行时才被调度。ThreadFactory.newThread()

含义:在严格使用时间片的系统上,只有在整个程序中没有其他具有更高优先级的线程要求调度时,才会给你一个时间片来执行。根据您的应用程序的实际繁忙程度,您可能会每隔一段时间被安排一次,或者您可能根本没有被安排。

于 2010-10-05T22:50:06.577 回答