我所在时区的早安.
我正在使用线程池开发一个小型Http机器人,该机器人从每个页面的链接移动到链接.当我找到新链接时,我创建了一个新线程来探索该新页面.
伪代码.
pool = Executors.newFixedThreadPool(40);
pool.execute(new Exploit(tree.getRoot()));
在这种情况下,Exploit是一个内部类,该类实现Runnable接口并可以访问池,因此每次一个线程找到链接时,都将使用该池来添加新的“线程”,如下所示:
for(Link n : links){
pool.execute(new Exploit(n));
}
我看到了很多使用ExecutorService类的示例,但是它们都使用相同的代码,例如:
ExecutorService executor = Executors.newFixedThreadPool(NTHREDS);
for (int i = 0; i < 500; i++) {
Runnable worker = new MyRunnable(10000000L + i);
executor.execute(worker);
}
// This will make the executor accept no new threads
// and finish all existing threads in the queue
executor.shutdown();
在上面的代码中,线程数是静态的,因此当代码调用shutdown时,所有线程已添加到池中.我无法遵循此代码,因为在我的情况下,我没有要添加的静态线程数.我停止向池中添加更多线程的条件是当我到达搜索深度级别时.所以我的问题是,如何在主线程中调用executor.shutdown?我可以在主线程中使用任何一种连接吗?
提前致谢.
最好的祝福
解决方法:
您可以看一下Phaser.您仍然可以使用固定数量的线程,但是每次找到链接时,您都可以注册另一方并根据该链接提交可运行对象.
Phaser phaser = new Phaser(1);
ExecutorService e = Executors.newFixedThreadPool(n);
public void crawl(final String url){
visit(url);
phaser.arriveAndAwaitAdvance();
e.shutdown();
}
private void visit(String url){
phaser.register();
e.submit(new Runnable(){
public void run(){
//visit link maybe another visit(url)
phaser.arrive();
}
});
}
在这一点上,e.shutdown()在访问所有链接之前永远不会发生.