有没有办法告诉ExecutorService
在固定线程池场景中关闭空闲线程?
问候!
::编辑:好的,我很沮丧。我现在已经切换到允许我使用以下构造函数指定 keepAliveTime 的 ThreadPoolExecutor:
private final LinkedBlockingQueue<Runnable> threadPool = new LinkedBlockingQueue<Runnable>()
public Crawler(String startingUrl, int numThreads, int depth) {
System.setProperty("http.agent", "");
// System.setProperty(LocalLog.LOCAL_LOG_LEVEL_PROPERTY, "info");
this.url = startingUrl;
this.maxDepth = depth;
executorService = new ThreadPoolExecutor(
numThreads,
numThreads,
2000,
TimeUnit.MILLISECONDS,
threadPool,
new ThreadPoolExecutor.CallerRunsPolicy());
databaseHandler = new DatabaseHandler();
try {
databaseHandler.init();
} catch (final SQLException e) {
e.printStackTrace();
}
}
// this method is invoked by each Runnable when it found new links
@Override
public void queueLink(String link, int currentDepth) throws Exception {
if (currentDepth < maxDepth) {
final LinkFinder lf = new LinkFinder(link, currentDepth, this);
executorService.execute(lf);
} else {
System.out.println("max depth reached!");
System.out.println("num queued tasks: " + threadPool.size());
}
}
每个新的 Runnable 都接收一个当前深度属性。在每个 Runnable 的最后一行,currentDepth 加 1。当然“达到最大深度”会按预期打印出来,以及“队列中的任务数:0”。然而,线程继续运行数小时。
我在操作时的印象是参数 keepAliveTime 和 TimeUnit.MILLISECONDS 将确保在两秒钟的空闲时间后,线程被关闭(假设没有其他任务排队)。
我错过了什么?我的意思是,我可以计算我点击 else 语句然后手动关闭执行器的次数,但是由于 ThreadPoolExecutor 已经提供了基于时间的行为,我宁愿坚持下去。
现在我认为这与我制定的政策有关……我会调查的。不管怎么说,多谢拉
问候!