繁体   English   中英

工作人员完成后将新任务提交给执行者

[英]Submit new task to executor after worker finishes

我正在研究访问页面并提取链接以查找特定域的Web搜寻器,如果找不到,它将查看提取的链接并重复直到达到页面限制或找到页面为止。 我发现自己正在努力提出合理的逻辑,以使该僵尸程序在提取链接后继续让任务排队,因为该任务正在快速完成,并且没有足够的时间来提交新提取的链接。 我该如何实施,使搜寻器在没有执行程序的情况下等待其关闭,然后再关闭执行器? 我已经包括了我的多线程实现的基本概述。 我将最大线程数设置为3,并提交example.com 10次(种子域)

Spawn Thread访问站点并提取链接,然后将其返回为字符串。 我的问题是我需要能够获得这些结果,然后将其放入队列。 但是到那时队列已经完成。 有什么建议么?

更新因此,为了澄清起见,我的问题是,当我提交种子并获得结果时,我无法获取它来继续搜索返回的种子。 除非我阻止并等待结果,然后手动添加它们。

更新2为了进一步说明,我试图防止在future.get发生阻塞,因此我可以添加返回的结果,因为它们将被安排为任务。

            int MaxThreads = 3;
            ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(MaxThreads); // How many threads
            List<Future<String>> resultList = new ArrayList<>();// Create results list

            for (int i = 0; i < 10; i ++) {
                SpawnThread task  = new SpawnThread("example.com");// Create Tasks
                Future<String> result = executor.submit(task);//Launch tasks
                //System.out.println("Added " + CurrentNum + " to the que!");
                resultList.add(result);//Store Task Result
            }

             for(Future<String> future : resultList) //Loop through results
                {
                    String resultfinished;
                    try {
                        resultfinished = future.get();
                        System.out.println(resultfinished);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    } catch (ExecutionException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }

                }
            executor.shutdown();

我认为我需要的是一个不阻塞的队列,可以将结果重新添加到允许新域进行爬网的列表中,但是我似乎无法使其正常工作。

BlockingQueue queue = new ArrayBlockingQueue(1024);
        Executor executor = Executors.newFixedThreadPool(4);
        CompletionService<List<String>> completionService = 
                 new ExecutorCompletionService<List<String>>(executor);
        List<String> pagesToVisit = new ArrayList<String>();
        Set<String> pagesVisited = new HashSet<String>();

        String SeedPage = "https://example.com/";
        String currentURL = null;

        boolean done = false;
        while(!done) {

             int listsize = pagesToVisit.size();
             if(pagesToVisit.isEmpty())
             {
                 currentURL = SeedPage;
                 pagesVisited.add(SeedPage);
                 listsize = pagesToVisit.size() + 1;
              }
             else
             {
                 currentURL = nextUrl();
             }


             for(int k = 0; k < listsize; k ++)
             {

                 completionService.submit(new Spider(currentURL,"IP","PORT" ) {
                 });
             }

              int received = 0;
              boolean errors = false;
              while(received < listsize  && !errors)
              {
                  Thread.sleep(1000);
                  Future<List<String>> resultFuture = completionService.take(); //blocks if none available
                  try
                  {
                      List<String> result = resultFuture.get();
                      pagesToVisit.addAll(result);
                      received ++; 
                  }
                  catch(Exception e)
                  {
                               //log
                            e.printStackTrace();
                            errors = true;
                  }
              }

          }

我不确定我是否让你问对了,但是

您可以使用awaitTermination(); 方法

公共布尔awaitTermination(长时间超时,TimeUnit单位)引发InterruptedException

阻塞直到关闭请求后所有任务完成执行,或者发生超时,或者当前线程被中断(以先发生的为准)。

参数:timeout-等待的最大时间单位-timeout参数的时间单位

返回:如果此执行程序终止,则返回true;如果终止之前超时,则返回false

抛出:InterruptedException-如果在等待时被中断

例如

try{
executor.awaitTermination(5, TimeUnit.Seconds);
}catch(InterruptedException e)
{
// Catch block
}

shutdown()方法不等待线程完成

启动有序关闭,在该关闭中执行先前提交的任务,但不接受任何新任务。 如果已关闭,则调用不会产生任何其他影响。 此方法不等待先前提交的任务完成执行。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM