2010-10-04 98 views
1

我想调一个线程,其执行以下操作:的ThreadPoolExecutor - ArrayBlockingQueue ...等待它删除的元素之前形成队列

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

队列使用是一个ArrayBlockingQueue

Quesize = 20

背景:
线程尝试读取请求并对其执行操作。然而,最终的请求增加了很多,线程总是很忙,并且消耗1个CPU,这使得它成为一个资源管理器。

我想这样做,而是在间隔中对请求进行采样并处理它们。其他请求可以安全地忽略。

我所要做的就是在“操作”函数中进行睡眠,以便线程每次睡眠一段时间并释放CPU。

Quesiton:
不过,我想知道是否有使用基本上自身休眠它读取下一个元素之前的某个时候队列的方式。这将是理想的,因为在执行过程中休眠任务并保持执行不完整对我来说听起来并不合适。

请让我知道如果您有任何其他建议以及对任务

感谢。

编辑: 我添加了一个后续问题here 纠正maxpool大小为1 [写在一个急速] ..感谢蒂姆指出。

+1

这不是一个真正的“资源猪”,有很多工作要做。你真的想要人为地减缓请求吗?为什么请求(客户端?)发送得比他们可以处理的速度快?这是不可持续的。 – AngerClown 2010-10-05 00:19:26

+0

好点。如果客户发出很多因完整队列而被拒绝的请求,那么他们正在浪费可能在客户端和执行程序之间更好地平衡的CPU。队列是一个缓冲区,可以随时间“平滑”负载;拒绝应该是罕见的,不是常规的。 – erickson 2010-10-05 00:27:23

+0

客户不是真正意义上的请求者的专用客户端。请求者有一个专用客户端,根据请求的数量进行扩展。我正在工作的客户端就像是一个额外的日志记录工具,监控操作类型..采样仍然很好,以获取请求图片..希望是有道理的。 – codeObserver 2010-10-05 00:55:44

回答

1

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

在排队的任务中暂停是强制线程闲置而不管排队的任务的唯一方法。现在,“睡眠”不必与“工作”在同一个任务中,您可以在每个真实任务之后排队一个单独的休息任务,这可能会使实施更加清晰。更重要的是,如果工作是返回结果的Callable,则分离为两个任务将允许您尽快获得结果。

作为一种改进,不是在每个任务之间的固定时间间隔内休眠,而是可以将执行“限制”到指定的速率。这将允许您避免在任务之间不必要的等待,同时避免在指定的时间间隔内执行太多任务。你可以用read another answer of mine来实现这个简单的方法,使用DelayQueue

1

你可以继承线程池,并覆盖beforeExecute休眠一段时间:

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

    } 

但看到人为放慢队列可能不是一个好主意AngerClown的评论。

+0

谢谢,Thilo ..我认为BeforeExecute可能会做到这一点。如果工作正常,将会做出更改并接受答案:)。保持线程打开的情况下,有更多的想法:) – codeObserver 2010-10-05 20:57:19

+0

+1提到beforeExecute方法。人们有时非常执着于ExecutorService抽象,他们往往忘记了ThreadPoolExecutor实现也有一些整洁的产品。 – 2010-10-05 22:52:29

+0

我试着用这种方法修补。有趣的是,@times beforeExecute()被调用,然后立即执行任务而不休眠,然后在休眠时间结束后重新执行任务。我正在使用线程池,并且只有一个线程[请参阅我的问题中的详细信息] ..我是否缺少某些内容? – codeObserver 2010-10-06 23:04:38

1

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

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

含义:在严格使用时间分片的系统中,如果整个程序中没有其他线程具有更高的优先级请求被调度,则只会给予一个时间片来执行。根据您的应用程序的实际情况而定,您可能会每隔一段时间安排一次,否则您可能根本无法安排。

+0

谢谢..我已经考虑过这种方法,但恐怕它可能会让我的线程饿死。另外,我的线程正在尝试对数据进行采样,因此我想要一个真实的世界图片来说明发生了什么......这样做可能会使样本偏斜到只有CPU处于低电平的时间......这会破坏线程的目的。线程执行的任务也非常小[但是任务太多],所以我认为睡眠可能会更好。同意? – codeObserver 2010-10-05 23:32:50

+0

是的,同意了。我认为蒂罗的解决方案是最好的,这就是为什么我投了票。 – 2010-10-06 00:00:46

1

线程消耗100%CPU的原因是因为它的工作量比它能处理的要多。在任务之间添加延迟无法解决此问题。这只会让事情变得更糟。

相反,你应该看看为什么你的任务消耗了太多的CPU,与一个分析器,并改变它们,以便消耗更少的CPU,直到你发现你的线程能够跟上,它不再消耗100%的CPU。

+0

这是一个明显的答案......它就像Facebook太忙,并延迟登录以防止人们使用网络。 – 2010-12-25 22:28:16

+0

@Javier,facebook几乎无法控制请求的进入速度。有些人试图故意让服务器负载过重,看看会发生什么。你的代码可能会假设工作负载是“友善的” – 2010-12-26 08:23:03