java - 在动态线程号中调用 ExecutorService.shutdown

标签 java multithreading concurrency executorservice

早上好,我所在的时区。

我正在使用线程池开发一个小型 Http 机器人,它在每个页面中从一个链接移动到另一个链接。当我找到一个新链接时,我会创建一个新线程来探索该新页面。 伪代码。

pool = Executors.newFixedThreadPool(40);

pool.execute(new Exploit(tree.getRoot()));

在这种情况下,Exploit 是一个实现 Runnable 接口(interface)并可以访问池的内部类,因此每次一个线程找到一个链接时,将使用池以这种方式添加一个新的“线程”:

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();

在上面的代码中,线程数是静态的,所以当代码调用关闭时,所有线程都已经添加到池中。我无法遵循这段代码,因为在我的例子中,我没有静态的线程数加上。我向池中添加更多线程的停止条件是当我达到搜索深度时。所以我的问题是,我如何在主线程中调用 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() 将永远不会发生,直到所有链接都被访问过。

关于java - 在动态线程号中调用 ExecutorService.shutdown,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9802614/

相关文章:

ios - 如果辅助线程是由 NSThread 创建的,可以将分离状态更改为可连接状态吗?

java - 在 Vaadin 7 中调用 VaadinSession getAttribute 时需要锁定

java - 为什么并行流不使用ForkJoinPool的所有线程?

java - 我的java代码不同步

python - 为什么这个多进程程序比它的非并发版本运行得慢?

c - 读取内存屏障如何在存在中断的情况下工作?

java - 将依赖项注入(inject)静态字段

java - 使用 LuaJava 时如何处理 Lua 代码执行?

Java : Help need to typecast a String value into a char

java - 任意顺序的正则表达式匹配