3

我找不到使用最新的 JAVA 并发例程的这种特定情况的示例。

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

是否有针对这种特定类型案例的 Java 并发进程?

4

4 回答 4

9

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

执行服务: 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

获取一个新的 Thread 固定线程池,处理最大。10 线程一次:

ExecutorService threadPool = Executors.newFixedThreadPool(10);

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

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

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

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

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

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

于 2013-02-01T19:08:20.117 回答
2

我有同样的任务:我使用BlockingQueuejava.util.concurrent包的。我创建了 X 个工作线程,它从队列中读取一个动作,处理它,并在准备好时执行下一个动作。这很简单,而且效果很好。

如果你使用 X = 10 Worker 线程,那么你的任务就解决了。

于 2013-02-01T19:03:06.790 回答
1

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

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

于 2013-02-01T19:07:06.077 回答
0

如果您实际上无权访问线程的创建,而您只管理队列访问,则解决方案可能只是使用一个Semaphore对象(请参阅文档页面)。

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

在访问队列以进行项目处理之前,线程将首先从信号量获取许可,如果max_threads多个线程已经开始处理队列中的项目,则该信号量将阻塞。

在某个线程处理了一个项目之后,该线程应该最终释放许可,从而允许更多线程处理其他项目。

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

semaphore.acquire().
try {
    // retrieve item from queue and process it
}
finally {
    semaphore.release();
}
于 2013-02-02T01:00:48.493 回答