这是我的情况。我必须运行X搜索(10-200之间)获取每个搜索的结果并附加它们。我想为搜索添加一些并发性,但我希望能够限制它。我的意思是我不想踢200个线程并等待所有人完成。我想启动N个线程,并在每个线程完成时启动一个新线程直到所有线程完成。
我知道我可以从头开始写这个但是我想知道是否已经存在一个简单的模式或库?我讨厌重新创造轮子。
感谢。
答案 0 :(得分:6)
java.util.Concurrent
中的执行程序框架是创建线程池并在其上调度任务的标准方法。您创建了一个包含多个主题的java.util.concurrent.ThreadPoolExecutor
并在其上提交Runnable
或Callable<V>
个实例(Callable
就像可以运行一样,但能够返回结果) 。每次提交任务时,都会得到一个Future<V>
实例作为回报,可以将其视为指向未来结果的指针。您可以使用get()
方法查询这些未来实例是否已完成或仅执行阻止等待。
答案 1 :(得分:1)
从java.util.concurrent查看CompletionService和TimingThreadPool 例如
private final Executor exec = new TimingThreadPool( NUMBER_MIN_THREADS, 2, 10, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(NUMBER_IN_QUEUE ),
new ThreadPoolExecutor.CallerRunsPolicy() );
private final CompletionService<DownloadStatus> service = new ExecutorCompletionService<DownloadStatus>( exec );
然后进行每次搜索
service.submit( <a callable doing the search>);
说有N个
当所有人都在服务队列
上发送等待结果时for (int i = 0; i < N); i++)
{
final Future<DownloadStatus> fut = service.take();
final Object d = fut.get(); // This is what the callable returns
答案 2 :(得分:0)
设计您的程序,使每个单独的任务都是Callable
。然后,您可以从the Executors class选择最适合您的执行者。
答案 3 :(得分:0)
我想我会使用Executors.newfixedThreadPool(int numberOfThreads)做你想做的事情,除了它重新使用线程而不是创建新线程。
你给它一个Runnable(如果你想要返回结果和/或异常,你可以给它一个Callable),一旦线程空闲,它就会在一个可用的线程中执行该runnable。
如上所述,您可以使用Callable获取结果,但您也可以使用Runnable并将结果转储到例如像LinkedBlockingQueue一样BlockingQueue。这样,一旦你的线程产生结果,你就可以把结果扼杀。