呼び出しを並列化したいのですが、ファイル全体をメモリに読み込む必要があるかどうかわかりません
ExecutorService
境界のある でを使用する必要がありますBlockingQueue
。BlockingQueue
100 万行を読み込んで、いっぱいになるまでスレッド プールにジョブを送信します。このようにして、事前にファイルのすべての行を読み取ることなく、100 (または最適な数) の HTTP 要求を同時に実行できます。
RejectedExecutionHandler
キューがいっぱいになった場合にブロックする を設定する必要があります。これは、呼び出し元がハンドラーを実行するよりも優れています。
BlockingQueue<Runnable> queue = new ArrayBlockingQueue<Runnable>(100);
// NOTE: you want the min and max thread numbers here to be the same value
ThreadPoolExecutor threadPool =
new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, queue);
// we need our RejectedExecutionHandler to block if the queue is full
threadPool.setRejectedExecutionHandler(new RejectedExecutionHandler() {
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
try {
// this will block the producer until there's room in the queue
executor.getQueue().put(r);
} catch (InterruptedException e) {
throw new RejectedExecutionException(
"Unexpected InterruptedException", e);
}
}
});
// now read in the urls
while ((String url = urlReader.readLine()) != null) {
// submit them to the thread-pool. this may block.
threadPool.submit(new DownloadUrlRunnable(url));
}
// after we submit we have to shutdown the pool
threadPool.shutdown();
// wait for them to complete
threadPool.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
...
private class DownloadUrlRunnable implements Runnable {
private final String url;
public DownloadUrlRunnable(String url) {
this.url = url;
}
public void run() {
// download the URL
}
}