限制线程数和Java并发

时间:2013-02-01 18:56:31

标签: java multithreading concurrency java.util.concurrent

我无法使用最新的JAVA并发例程找到此特定情况的示例。

我计划使用threads处理来自开放队列的项目,该队列可能包含0到数千个请求。我想限制所以在任何给定的时间都有不少于0且不超过10个处理队列项的线程。

是否存在针对此特定类型案例的Java并发流程?

4 个答案:

答案 0 :(得分:9)

我认为线程池是您正在寻找的。看看ExecutorService和Executors。

ExecutorService:http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/ExecutorService.html

执行人员:http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/Executors.html

获取一个处理最大值的新线程修复线程池。 10个线程:

ExecutorService threadPool = Executors.newFixedThreadPool(10);

使用提交方法,您可以将Callables或Runnables传递给池。

对于您的用例,您需要一个查看队列的进程,如果有新请求,则必须创建Callable或Runnable并将其传递给线程池。游泳池确保最大。一次执行10个线程。

这是一个非常小的教程:http://www.math.uni-hamburg.de/doc/java/tutorial/essential/threads/group.html

使用线程池的一个好处是submit方法返回一个Future对象,它支持执行线程的返回类型。

未来:http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/Future.html

我希望这可以帮助您解决问题。

答案 1 :(得分:2)

我有同样的任务: 我使用了BlockingQueue包的java.util.concurrent。我创建了X工作线程,它从队列中读取一个动作,处理它,并在准备好时接下一个。这很简单,工作正常。

如果您使用X = 10个工作线程,那么您的任务就会解决。

答案 2 :(得分:1)

看起来你需要一个corePoolSize = 0和maximumPoolSize = 10的线程池执行器。

http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/ThreadPoolExecutor.html

答案 3 :(得分:0)

如果您实际上无法访问线程的创建,并且只管理队列访问,则解决方案可能只是使用Semaphore对象(请参阅docs page)。

想法是以访问队列的相同方式访问全局信号量,将其初始化为数字max_threads(例如10)。

在访问队列进行项目处理之前,线程首先acquire来自信号量的许可,如果max_threads个线程已经开始处理队列中的项目,则会阻止该许可。

某个线程处理完一个项目后,该线程最终应该release许可,从而允许更多线程处理其他项目。

请注意,许可证的获取/释放应使用try-finally块完成,这样即使从项目处理中抛出一些异常,信号量仍保持一致状态。代码应如下所示:

semaphore.acquire().
try {
    // retrieve item from queue and process it
}
finally {
    semaphore.release();
}